I am trying to use the example of the network extension. Now I have completed the necessary profile configuration and other content. After I try to run, a corresponding small window will pop up, but no matter how long after I click start, no matter what connection I send, it does not respond and display. I would like to know how to open a connection on the port being filtered? And then to make the SimpleFirewall work as expected?
Networking
RSS for tagExplore the networking protocols and technologies used by the device to connect to Wi-Fi networks, Bluetooth devices, and cellular data services.
Post
Replies
Boosts
Views
Activity
What are the possible transitions within NWConnection.State?
Are cancelled and failed both terminal states? (Implying that I should drop the connection and attempt to set up a new one if I want to reconnect?)
The common flow of setup -> preparing -> ready I've observed, but I wasn't sure how waiting fit in.
What transitions are legal (and managed) by NWConnection?
(mermaid couldn't handle this diagram - but I wrote it out anyway) Are these transitions all valid?
[*] --> setup
cancelled --> [*]
failed --> [*]
setup --> preparing
preparing -> ready
preparing -> cancelled
preparing -> failed
ready -> waiting
ready -> failed
ready -> cancelled
waiting -> cancelled
waiting -> preparing
waiting -> failed
I am using QLPreviewController with SwiftUI using UIViewControllerRepresentable. If I try to delete or insert pages of large size PDF, QLPreviewController is not calling delegate methods (didUpdateContentsOf, didSaveEditedCopyOf).
struct QuickLookController: UIViewControllerRepresentable {
@Environment(\.dismiss) var dismiss
weak var delegate: QLPreviewControllerDelegate?
weak var dataSource: QLPreviewControllerDataSource?
func makeUIViewController(context: Context) -> UINavigationController {
let controller = context.coordinator.controller
controller.delegate = delegate
controller.dataSource = dataSource
controller.navigationItem.rightBarButtonItem = context.coordinator.dismissButton
return UINavigationController(rootViewController: controller)
}
func updateUIViewController(_ viewController: UINavigationController, context: UIViewControllerRepresentableContext<QuickLookController>) { }
func makeCoordinator() -> Self.Coordinator {
.init(parent: self)
}
@MainActor
class Coordinator: NSObject {
var parent: QuickLookController
init(parent: QuickLookController) {
self.parent = parent
}
lazy var controller: QLPreviewController = {
let controller = QLPreviewController()
return controller
}()
lazy var dismissButton: UIBarButtonItem = {
let button = UIBarButtonItem(
title: NSLocalizedString("Done", comment: ""),
style: .plain,
target: self,
action: #selector(rightButtonTapped(_:))
)
button.tag = 2
return button
}()
@objc func rightButtonTapped(_ sender: Any) {
controller.dismiss(animated: true)
}
}
}
// MARK: QuickLook
extension ViewerModel: QLPreviewControllerDataSource, QLPreviewControllerDelegate {
public func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
1
}
public func previewController(
_ controller: QLPreviewController,
previewItemAt index: Int
) -> QLPreviewItem {
let title = self.document
.documentURL?
.lastPathComponent ?? ""
let url = PDFManager
.directory
.appendingPathComponent(title) as NSURL
return url as QLPreviewItem
}
public func previewControllerDidDismiss(_ controller: QLPreviewController) {
}
public func previewControllerWillDismiss(_ controller: QLPreviewController) {
}
✔️ It's same even if I set it to updateContents
public func previewController(_ controller: QLPreviewController, editingModeFor previewItem: QLPreviewItem) -> QLPreviewItemEditingMode {
.createCopy
}
✔️ Not called with Large Size PDF
public func previewController(_ controller: QLPreviewController, didUpdateContentsOf previewItem: QLPreviewItem) {
}
✔️ Not called with Large Size PDF
public func previewController(_ controller: QLPreviewController, didSaveEditedCopyOf previewItem: QLPreviewItem, at modifiedContentsURL: URL) {
}
}
i want to make a bluetooth classic code
i found sample code at apple web site
just like below
https://developer.apple.com/documentation/corebluetooth/using_core_bluetooth_classic
but i can't use...
i need some explanation for this,
i watched video below
https://developer.apple.com/videos/play/wwdc2019/901
but
i need more easy and detailed explanation.
this is all~~~ about ios bluetooth classic explanation in text.
please help me
is any other clips in youtube or
sites that explain this easy and in detail ?
Hi,
I'm trying to use PencilKit over PDFKit as described in https://developer.apple.com/videos/play/wwdc2022/10089/. The thing is I open my custom UIDocument and initialize all its content to feed PDFView. Everything seems to work, I Input sketches in the canvas, PDFPageOverlayViewProvider's overlayView(for:) generates canvas correctly (it seems) but when editing finishes : willEndDisplayingOverlayView never gets called, and when I save the UIDocument (I use document.close(completionHandler:)) contents(forType:) never sees my custom PDFPages and I get no content for sketches.
Does anyone of you have an idea of the lifecycle we should follow to get the methods called ?
Sincerely yours
Is it possible to disable Local network option from xcode, so that do not popup notification to user about turn off /on and user could not disable or enable it
Hello,
I work for a USA cell phone carrier and we have our own SIM cards. We'd like to add a carrier bundle so we can have our carrier settings predefined in iOS devices. Could someone explain what the process is?
Thanks
Hello there, I am trying to follow along with the video and copy the example shown here in SwiftUI. I am given the error Cannot assign value of type 'UIView' to type 'PKCanvasView?' on this line: resultView = overlayView
It is totally possible that I am botching the whole thing up but I would appreciate it if someone looked over my code. Thanks.
code:
// ContentView.swift
import SwiftUI
import PDFKit
import PencilKit
import Foundation
import UIKit
struct PDFUIView: View {
let pdfDoc: PDFDocument
let pdfView: PDFView
init() {
let url = Bundle.main.url(forResource: "example", withExtension: "pdf")!
pdfDoc = PDFDocument(url: url)!
pdfView = PDFView()
}
var body: some View {
VStack {
PDFKitView(showing: pdfDoc, pdfView: pdfView)
}
.padding()
}
}
#Preview {
PDFUIView()
}
struct PDFKitView: UIViewRepresentable {
let pdfDocument: PDFDocument
let pdfView: PDFView
init(showing pdfDoc: PDFDocument, pdfView:PDFView) {
self.pdfDocument = pdfDoc
self.pdfView = pdfView
}
func makeUIView(context: Context) -> PDFView {
pdfView.usePageViewController(true)
pdfView.autoScales = true
pdfView.pageOverlayViewProvider = context.coordinator
pdfView.displayMode = .singlePageContinuous
pdfView.isUserInteractionEnabled = true
pdfView.document = pdfDocument
pdfView.delegate = context.coordinator
return pdfView
}
func updateUIView(_ pdfView: PDFView, context: Context) {
pdfView.document = pdfDocument
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
}
class Coordinator: NSObject, PDFPageOverlayViewProvider, PDFViewDelegate {
var pageToViewMapping = [PDFPage: UIView]()
func pdfView(_ view: PDFView, overlayViewFor page: PDFPage) -> UIView? {
var resultView: PKCanvasView? = nil
if let overlayView = pageToViewMapping[page] {
resultView = overlayView
} else {
var canvasView = PKCanvasView(frame: .zero)
canvasView.drawingPolicy = .anyInput
canvasView.tool = PKInkingTool(.pen, color: .systemCyan, width: 20)
canvasView.backgroundColor = UIColor.clear
pageToViewMapping[page] = canvasView
resultView = canvasView
}
let page = page as! MyPDFPage
if let drawing = page.drawing {
resultView?.drawing = drawing
}
return resultView
}
func pdfView(_ pdfView: PDFView, willDisplayOverlayView overlayView: UIView, for page: PDFPage) {
guard let overlayView = overlayView as? PKCanvasView else {
return
}
guard let canvasView = pageToViewMapping[page] else {
return
}
let page = page as! MyPDFPage
page.drawing = overlayView.drawing
pageToViewMapping.removeValue(forKey: page)
}
class MyPDFAnnotation: PDFAnnotation {
override func draw(with box: PDFDisplayBox, in context: CGContext) {
UIGraphicsPushContext(context)
context.saveGState()
let page = self.page as! MyPDFPage
if let drawing = page.drawing {
let image = drawing.image(from: drawing.bounds, scale: 1)
image.draw(in: drawing.bounds)
}
context.restoreGState()
UIGraphicsPopContext()
}
}
class MyPDFPage: PDFPage {
var drawing: PKDrawing?
}
}
Hello,
I'm struggling to understand how I can use NSXPC API to communicate between two processes on iOS. The problem which I want to solve is how to pass some information from VPN tunnel to the VPN app.
I'm looking at the XPC documentation and for iOS I can create NSXPCListener only with the following functions:
service()
anonymous()
Both return NSXPCListener instance. But the question remains, how to connect to such an instance?
In NSXPConnection API I see only one option for iOS:
init(listenerEndpoint: NSXPCListenerEndpoint)
Other constructors accepting serviceName or machServiceName are available only form macOS.
I feel like the problem of communicating between two processes should be easy, but surprisingly I did find it quite difficult on iOS. Can you please advice if this is a proper API for my use case? Or maybe is there some better one, which I'm not aware of?
If this is a proper API, how should I create a connection between two apps? How to pass a listener from one process to the other?
Our application (VPN solution) works well on macOS 13 and this issue only occurred on macOS 14 beta.
This issue is:
If we connect the cable to a Mac mini’s ethernet port, and enable the VPN in our application, then the Tunnel is enabled under System Settings->Network->VPN & Filter, after that, the DNS stops resolving.
If we use a “USB-C LAN” adapter to connect the cable to Mac mini’s USB-C port, this issue disappears. Only enable Wi-Fi can also avoid this issue.
The confusion is what’s the difference between connect to Ethernet directly and use an adapter?
How often does Apple update IPs posted in https://mask-api.icloud.com/egress-ip-ranges.csv ?
Hi Team,
I'm trying to capture inbound traffic for DNS responses and have experimented with the following rules, but they did not work.
NENetworkRule *dnsInboundTraffic = [[NENetworkRule alloc] initWithRemoteNetwork:nil remotePrefix:0 localNetwork:[NWHostEndpoint endpointWithHostname:@"0.0.0.0" port:@"53"] localPrefix:0 protocol:NENetworkRuleProtocolUDP direction:NETrafficDirectionInbound];
settings.includedNetworkRules = @[dnsInboundTraffic];
Could you please correct me if I'm making any mistakes while setting the rules?
Hello,
We have functionality in an existing app, have to generate a pdf and it should be printable in the A4. The PDF is almost 8 to 10 pages
I have applied below solution:
Loading the HTML template on the WKwebview and doing a few operations on the content and converting it into a pdf.
Converting the HTML into a string
Replacing a few data with dynamic content
Issue:
The solutions worked fine in the previous OS(14.5,15.5,16.1), it is not working on the latest os 16.6
The Table background CSS is not Rendering. I have tried both Inline and external CSS loading but still facing the same issue.
Approch1:
func createPDF(formmatter: UIViewPrintFormatter, filename: String) -> String {
let attributedString = NSAttributedString(string: "This is a test", attributes: [NSAttributedString.Key.foregroundColor: UIColor.red])
let printFormatter = UISimpleTextPrintFormatter(attributedText: attributedString)
let render = UIPrintPageRenderer()
render.addPrintFormatter(printFormatter, startingAtPageAt: 0)
// 2. Assign print formatter to UIPrintPageRenderer
//let render = UIPrintPageRenderer()
render.addPrintFormatter(formmatter, startingAtPageAt: 0)
// 3. Assign paperRect and printableRect
let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi
let printable = page.insetBy(dx: 20, dy: 20)
//let printable = page.inset(by: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10));
render.setValue(NSValue(cgRect: page), forKey: "paperRect")
render.setValue(NSValue(cgRect: printable), forKey: "printableRect")
// 4. Create PDF context and draw
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, CGRect.zero, nil)
for i in 1...render.numberOfPages {
UIGraphicsBeginPDFPage();
let bounds = UIGraphicsGetPDFContextBounds()
render.drawPage(at: i - 1, in: bounds)
}
UIGraphicsEndPDFContext();
// 5. Save PDF file
var dst = self.getDestinationPath(1)
if dst.contains("file://") {
dst = dst.replacingOccurrences(of: "file://", with: "")
}
//let path = "\(NSTemporaryDirectory())\(filename).pdf"
pdfData.write(toFile: dst, atomically: true)
print("open \(dst)")
return dst
}
}
Approach2:
But the pdf is Generating in a single page not multiple and it's not printable using the below solution.
func createPDFMethod(webView: WKWebView, title:String="samplepdf"){
let pdfConfiguration = WKPDFConfiguration()
/// Using `webView.scrollView.frame` allows us to capture the
// entire page, not just the visible portion
pdfConfiguration.rect = CGRect(x: 0, y: 0, width: webView.scrollView.contentSize.width, height: webView.scrollView.contentSize.height)
webView.createPDF(configuration: pdfConfiguration) { result in
switch result {
case .success(let data):
// Creates a path to the downloads directory
DispatchQueue.main.async {
let resourceDocPath = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last! as URL
let pdfNameFromUrl = "\(title).pdf"
let actualPath = resourceDocPath.appendingPathComponent(pdfNameFromUrl)
do {
try data.write(to: actualPath, options: .atomic)
print("pdf successfully saved!")
} catch {
print("Pdf could not be saved")
}
}
case .failure(let failure):
print(failure.localizedDescription)
}
}
}
It seems the issue is with UIGraphics or WKwebview formaters.
could you please help me to resolve this issue?
I'm implementing a VPN using the Network Extension Framework.
I've recently noticed that our VPN was sometimes reporting to be connected, but when I checked my IP address it would be my public one. This was a drastic change of behavior that didn't seem to be associated with any specific change we have done recently.
Originally I was trying to debug this issue in our App, but then I noticed that another VPN I'm using that's directly set up through System Settings in macOS (Ventura 13.5), and that is not running any of our code, is showing the same behavior.
In this case the VPN was set up through System Settings as an IKEv2 VPN, so there's no 3rd party vendor code running - just macOS doing its thing.
Both times I had this issue, the only thing that would fix it was rebooting the computer.
When checking netstat -nr -f inet I noticed that the order of the default routes changed when the issue got resolved:
When the VPN was connected but being ignored, the topmost route was en0, and the second route was ipsec.
When the VPN was connected and working fine, the topmost route was ipsec, and the second route was en0.
The same routing difference was visible for our own VPN network extension.
Any thoughts about how I can debug this further?
Given that this is not affecting only our VPN, but is also affecting an unrelated VPN managed by macOS it feels like it may be a macOS bug, but I'm not sure how to validate for that.
Hi.
i've app in swift for iOS and macOS, which using websocket
webSocketTask = URLSession.shared.webSocketTask(with: request)
//Session
let session = URLSession(configuration: configuration ?? .default, delegate: self, delegateQueue: OperationQueue())
and as the result, when user have turn on Private relay, user doesn't receive any informatiom from web socket, if user switch off this function, all is fine. Could you give some advise, how to setup client, or server to allow working websockets in that case?
I am having a video chat application using react js in the frontend and i have one SFU server which is based on Node js with WRTC library for supporting webRTC apis in the server side(M87).
App.js
import React, { useState, useRef, useEffect, useCallback } from "react";
import io from "socket.io-client";
import Video from "./Components/Video";
import { WebRTCUser } from "./types";
const pc_config = {
iceServers: [
// {
// urls: 'stun:[STUN_IP]:[PORT]',
// 'credentials': '[YOR CREDENTIALS]',
// 'username': '[USERNAME]'
// },
{
urls: "stun:stun.l.google.com:19302",
},
],
};
const SOCKET_SERVER_URL = "https://192.168.132.29:8080";
const App = () => {
const socketRef = useRef<SocketIOClient.Socket>();
......
..........
const createReceiverPeerConnection = useCallback((socketID: string) => {
try {
const pc = new RTCPeerConnection(pc_config);
// add pc to peerConnections object
receivePCsRef.current = { ...receivePCsRef.current, [socketID]: pc };
pc.onicecandidate = (e) => {
if (!(e.candidate && socketRef.current)) return;
console.log("receiver PC onicecandidate");
socketRef.current.emit("receiverCandidate", {
candidate: e.candidate,
receiverSocketID: socketRef.current.id,
senderSocketID: socketID,
});
};
pc.oniceconnectionstatechange = (e) => {
console.log(e);
};
pc.ontrack = (e) => {
console.log("ontrack success");
setUsers((oldUsers) =>
oldUsers
.filter((user) => user.id !== socketID)
.concat({
id: socketID,
stream: e.streams[0],
})
);
};
// return pc
return pc;
} catch (e) {
console.error(e);
return undefined;
}
}, []);
......
............
return (
<div>
<video
style={{
width: 240,
height: 240,
margin: 5,
backgroundColor: "black",
}}
muted
ref={localVideoRef}
autoPlay
/>
{users.map((user, index) => (
<Video key={index} stream={user.stream} />
))}
</div>
);
};
export default App;
server.js
let http = require("http");
let express = require("express");
let cors = require("cors");
let socketio = require("socket.io");
let wrtc = require("wrtc");
const fs = require("fs");
let https = require("https");
const port=8080;
const options = {
key: fs.readFileSync("../cert/cert.priv.key"),
cert: fs.readFileSync("../cert/cert.chain.pem"),
};
const app = express();
const server = https.createServer(options, app);
app.use(cors());
let receiverPCs = {};
let senderPCs = {};
let users = {};
let socketToRoom = {};
const pc_config = {
iceServers: [
// {
// urls: 'stun:[STUN_IP]:[PORT]',
// 'credentials': '[YOR CREDENTIALS]',
// 'username': '[USERNAME]'
// },
{
urls: "stun:stun.l.google.com:19302",
},
],
};
const isIncluded = (array, id) => array.some((item) => item.id === id);
const createReceiverPeerConnection = (socketID, socket, roomID) => {
const pc = new wrtc.RTCPeerConnection(pc_config);
if (receiverPCs[socketID]) receiverPCs[socketID] = pc;
else receiverPCs = { ...receiverPCs, [socketID]: pc };
pc.onicecandidate = (e) => {
//console.log(`socketID: ${socketID}'s receiverPeerConnection icecandidate`);
socket.to(socketID).emit("getSenderCandidate", {
candidate: e.candidate,
});
};
pc.oniceconnectionstatechange = (e) => {
//console.log(e);
};
pc.ontrack = (e) => {
if (users[roomID]) {
if (!isIncluded(users[roomID], socketID)) {
users[roomID].push({
id: socketID,
stream: e.streams[0],
});
} else return;
} else {
users[roomID] = [
{
id: socketID,
stream: e.streams[0],
},
];
}
socket.broadcast.to(roomID).emit("userEnter", { id: socketID });
};
return pc;
};
const createSenderPeerConnection = (
receiverSocketID,
senderSocketID,
socket,
roomID
) => {
const pc = new wrtc.RTCPeerConnection(pc_config);
if (senderPCs[senderSocketID]) {
senderPCs[senderSocketID].filter((user) => user.id !== receiverSocketID);
senderPCs[senderSocketID].push({ id: receiverSocketID, pc });
} else
senderPCs = {
...senderPCs,
[senderSocketID]: [{ id: receiverSocketID, pc }],
};
pc.onicecandidate = (e) => {
//console.log(`socketID: ${receiverSocketID}'s senderPeerConnection icecandidate`);
socket.to(receiverSocketID).emit("getReceiverCandidate", {
id: senderSocketID,
candidate: e.candidate,
});
};
pc.oniceconnectionstatechange = (e) => {
//console.log(e);
};
...
......
const closeReceiverPC = (socketID) => {
if (!receiverPCs[socketID]) return;
receiverPCs[socketID].close();
delete receiverPCs[socketID];
};
const closeSenderPCs = (socketID) => {
if (!senderPCs[socketID]) return;
senderPCs[socketID].forEach((senderPC) => {
senderPC.pc.close();
const eachSenderPC = senderPCs[senderPC.id].filter(
(sPC) => sPC.id === socketID
)[0];
if (!eachSenderPC) return;
eachSenderPC.pc.close();
senderPCs[senderPC.id] = senderPCs[senderPC.id].filter(
(sPC) => sPC.id !== socketID
);
});
delete senderPCs[socketID];
};
const io = socketio.listen(server);
io.sockets.on("connection", (socket) => {
socket.on("joinRoom", (data) => {
try {
let allUsers = getOtherUsersInRoom(data.id, data.roomID);
io.to(data.id).emit("allUsers", { users: allUsers });
} catch (error) {
console.log(error);
}
});
socket.on("senderOffer", async (data) => {
try {
socketToRoom[data.senderSocketID] = data.roomID;
let pc = createReceiverPeerConnection(
data.senderSocketID,
socket,
data.roomID
);
await pc.setRemoteDescription(data.sdp);
let sdp = await pc.createAnswer({
offerToReceiveAudio: true,
offerToReceiveVideo: true,
});
await pc.setLocalDescription(sdp);
socket.join(data.roomID);
io.to(data.senderSocketID).emit("getSenderAnswer", { sdp });
} catch (error) {
console.log(error);
}
});
socket.on("senderCandidate", async (data) => {
try {
let pc = receiverPCs[data.senderSocketID];
await pc.addIceCandidate(new wrtc.RTCIceCandidate(data.candidate));
} catch (error) {
console.log(error);
}
});
.....
.........
startServer(port);
function startServer(port) {
server.listen(port, () => {
console.log(`[INFO] Server app listening on port ${port}`);
});
}
Is there a way to find out which process an IP packet is going to or coming from? For example, I can examine each packet that comes and goes through the IP layer by using NEFilterPacketProvider. However, I want to know which process on the system is either expecting it or sent it. I don't want to use NEFilterDataProvider though.
Or, is there a way to programmatically get all the open/listening socket/port information so that I can piece together the process with the parsed packet data? I can get a list of all the running processes, but I can't seem to link these two pieces together to fully examine the network.
We have implemented System Extension with the capability of Packet Tunnel Provider. Our Tunnel is full tunnel, so we are getting all packets for all traffic(DNS requests packets, app data packets).
There are some DNS requests, we are not interested to resolve them. so we want to upstream these request to physical interface to resolve them.
so how can we upstream DNS request from one interface to other interface?
Hi!
despite the documentation saying otherwise, MultipeerConnectivityService appears to be unavailable in visionOS. Am I missing something or is this an issue with the current beta or (hopefully not 😬) the documentation?
https://developer.apple.com/documentation/realitykit/multipeerconnectivityservice
do {
entity.scene?.synchronizationService = try MultipeerConnectivityService(session: MultipeerSession.shared.session)
print("RealityKit synchronization started.")
} catch {
fatalError("RealityKit synchronization could not be started. Error: \(error.localizedDescription)")
}
Xcode complains 'MultipeerConnectivityService' is unavailable in visionOS, while the scene's synchronizationService property can be accessed...
HI,
I've created a virtual interface that used to get all outgoing packets, encapsulate with some VPN header, before resend them to their final destination through the physical adapter.
In order to choose the optimal MTU size that won't trigger fragmentation, I'd like to calculate the PMTU between the physical interface and the destination, subtracted by the encapsulation header size.
Then I'll set the virtual adapter's MTU with this result.
In order to do so, I poll the overall MTU cache using sysctl on macOS.
First, I verified that path mtu discovery is set
sysctl net.inet.tcp.path_mtu_discovery
net.inet.tcp.path_mtu_discovery: 1
Then, I tried to extract the cached pmtu for the gateway from the other size of the tunnel using the routing table .
static constexpr auto kSysctlMibLength = 6;
void get_pmtu_cache() {
std::map<std::string, std::uint32_t> res;
size_t size_needed = 0;
std::vector<char> route_table;
std::array<int, kSysctlMibLength> mib;
char *next = nullptr;
char *lim = nullptr;
struct rt_msghdr *rtm = nullptr;
struct sockaddr *saddr = nullptr;
struct sockaddr_in *sockin = nullptr;
char dest_ip_address[INET6_ADDRSTRLEN];
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = 0;
mib[4] = NET_RT_DUMP;
mib[5] = 0;
// stage 1 : get the routing table
// get routing table size
if (sysctl(mib.data(), kSysctlMibLength, nullptr, &size_needed, nullptr, 0) < 0) {
return;
}
// allocate local var according to size
route_table.reserve(size_needed);
// get routing table contents
if (sysctl(mib.data(), kSysctlMibLength, route_table.data(), &size_needed, nullptr, 0) < 0) {
return;
}
In the next step, I simple iterate the routing table elements and extract the following field for each destination : rt_msghdr.rt_metrics.rmx_mtu which is the path MTU from current endpoint to dest address.
lim = route_table.data() + size_needed;
for (next = route_table.data(); next < lim; next += rtm->rtm_msglen) {
rtm = reinterpret_cast<struct rt_msghdr *>(next);
saddr = reinterpret_cast<struct sockaddr *>(rtm + 1);
if ((rtm->rtm_addrs & RTA_DST) != 0) {
sockin = reinterpret_cast<struct sockaddr_in *>(saddr);
if (nullptr == inet_ntop(saddr->sa_family, &sockin->sin_addr.s_addr, dest_ip_address,INET6_ADDRSTRLEN)) {
continue;
}
const std::string dest_ip_address_str(dest_ip_address, strlen(dest_ip_address));
auto iter = res.find(dest_ip_address_str);
if (iter == res.end() || iter->second > rtm->rtm_rmx.rmx_mtu) {
res.insert_or_assign(dest_ip_address_str, rtm->rtm_rmx.rmx_mtu);
}
}
}
when I finally print all the values in res I see that my pmtu to my VPN server is 1500, even-though I've set the server's mtu size to 1000, and I check that ping -D -s 1500 <server> doesn't work since packets from size 1500 that cannot be fragmanted won't work.
auto item = res.find(vpn_server_address);
if (item == res.cend()) {
printf("no pmtu found to %s\n", vpn_server_address );
return;
}
ret = item->second;
I've tried to trigger the pmtu discovery to the VPN server using nscurl by sending https requests there, but the pmtu still remained on 1500.
Perhaps I'm missing something ?
do I extract the pmtu correctly ?
do I trigger the pmtu discovery by sending https messages using nscurl which is based on NSURLSession ?
Thanks !