how can handle network traffic in Transparent Proxy

I want Transparent Proxy(macOS Catalina) work below.
The detailed operation example is as follows.
  1. The user tries to connect to 10.10.10.10:1000.

  2. At the same time as this process, change the destination to 20.20.20.20:2000 to connect.

my question is
program <--> Transparent Proxy <--> remote connect
  1. how to connect remote server

  2. how to read data from flow

  3. how to write data from flow to remote connection

Code Block swift
override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool {
if let tcpflow = flow as? NEAppProxyTCPFlow {
// 1. how to connect remote server
// 2. how to read data from flow
// 3. how to write data from flow to remote connection
}
}

thank you

Accepted Answer
Ultimately, the nitty gritty details of doing this come down to how you want this to work in your environment, and with the destination endpoint, but a very general workflow could look something like:

1) Decide if the flow is one you want your transparent proxy to handle and return true/YES in handleNewFlow.

2) Cast the flow to the appropriate flow object for NEAppProxyTCPFlow or NEAppProxyUDPFlow as you are doing in your example.

3) Create the remote side of the connection with something like NWConnection, NWTCPConnection, nw_connection_t. This is where you could optional add logic to point at 20.20.20.20:2000 if needed. This is also where you could add additional logic to make these decisions.

4) Once your remote connection object is created I strongly advise you to create a management class for this object and for the flow copying operations. Pass your remote connection into this management class and start the remote connection. After the remote side of the connection has gone into the .ready state, open the flow you are handling.

5) Using the flow copying operations you defined in the management class, read from the flow and write the remote connection. Likewise, read from the remote connection and write to the flow. For NWConnection and NEAppProxyTCPFlow, take a look at these methods for doing so:
a) (Flow data) func write(Data, withCompletionHandler: (Error?) -> Void)
b) (Flow data) func readData(completionHandler: (Data?, Error?) -> Void)
c) (Remote data) [func send(content: Data?, contentContext: NWConnection.ContentContext, isComplete: Bool, completion:
NWConnection.SendCompletion)](https://developer.apple.com/documentation/network/nwconnection/3003626-send)
d) (Remote data) [func receive(minimumIncompleteLength: Int, maximumLength: Int, completion: (Data?,
NWConnection.ContentContext?, Bool, NWError?) -> Void)](https://developer.apple.com/documentation/network/nwconnection/2998572-receive)

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Thank you very much Matt.
I was successful in controlling network traffic.

I have one more question.

I got below log (in my TransparentProxy) when disconnected in program.
Code Block text
com.apple.networkextension (2684645955): Closing reads, not closed by plugin
com.apple.networkextension (2684645955): Closing writes, not sending close
com.apple.network nw_socket_handle_socket_event [C1:1] Socket received READ_CLOSE event

How can I catch some event when disconnected network in program
  1. I want to close flow - when connection is end in user program

  2. I want to close remote connection - when connection is end in user program


my code summary - read write between flow and remote connection
Code Block swift
func readFromRemote() {
self.connection?.receive(minimumIncompleteLength: 0, maximumLength: 2048) { (data, context, done, error) in
success then
self.appProxyFlow.write(data!) { (error) in
success then
self.readFromRemote()
}
}
}
func readFromFlow() {
appProxyFlow.readData { (data, readerror) in
success then
self.connection?.send(content: data, completion: NWConnection.SendCompletion.contentProcessed(({ (error) in
success then
self.readFromFlow()
})))
}
}


I was successful in controlling network traffic.

Excellent!


I want to close flow - when connection is end in user program
Take a look at:

func closeReadWithError(_ error: Error?)
func closeWriteWithError(_ error: Error?)


I want to close remote connection - when connection is end in user program

For the remote connection, make sure you observe the NWConnection.State. If moved into the .failed state run a connection.cancel() or a run this as needed to close the connection.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
how can handle network traffic in Transparent Proxy
 
 
Q