On Mar 1, 2010, at 1:13 AM, Jakub Bednar wrote: Hi Josh, On Dec 3, 2009, at 7:20 PM, Josh Graessley wrote: The recommeded solution is to manipulate connections to connect to your process instead of their intended destination. You may pass the intended destination out of band to your processs and then relay the data in user space between the socket connection from their process and your socket connection to their intended destination.
I have encountered a problem with this suggested solution and video streaming using Silverlight. The scenario is as follows:
1. I'm on an IPv4 network, though my interface has an IPv6 address set. 2. Browser (Safari/Firefox) creates an AF_INET6 socket and initiates a connect attempt.
3a. If there is no IPv6 redirection to my scanning process, the connect returns EHOSTUNREACH directly to the browser and it then tries an IPv4 address. That succeeds and streaming works.
3b. If there is an IPv6 redirection, the connect is successful (going to my process). And the failure happens in my process. But browser thinks that IPv6 is a good choice as it was successfully connected and never tries IPv4, therefore the streaming does not work.
That is definitely a problem. For blocking connect calls, you could probably send a request to your process to initiate the connect and if the connect fails, you could return the result to the caller. For non-blocking connect calls, I'm not sure how you could do this. Interesting point is, that this happens only on Snow Leopard. On Leopard with the same version of Firefox, there is also creation of AF_INET6 sockets, but the streaming works. Most probably the EHOSTUNREACH is returned before even a connect_out callback is called to my NKE. (Reordering of operations in the kernel between OS versions??)
With my original solution with scanning data on the fly without redirecting, this could not happen as the connect went directly. (This is also the way how this filters are solved on Windows). I think this could be a good feature request for the next version of the OS.
Please file a bug request for this. My question is, can I determine from the NKE, that this destination address has not a valid route in routing table? Or is there another way how to solve this problem?
The easiest way to determine whether there is a route is probably to a routing socket and send an RTM_GET message. I believe you should be able to create a routing socket inside of your kext and send the RTM_GET. Don't forget to set the loopback option on your routing socket. It's not easy but it would work. One downside is that an RTM_GET will have the response echoed to all routing sockets. You will need to filter all the data you get back on your routing socket to match the response to the request you made.
There are other problems you may run in to. Some future sockets may have other options set before the connect call that will affect which interface that connection occurs on. As your code may not be aware of those options (they're private to the OS and only used by a few internal bits of code so far), your code may cause problems for those sockets. As you mention above, the real solution is for some other way of tapping the traffic on a given socket so you don't have to perform another connect on another socket.
Unfortunately, the existing method of tapping traffic does have the serious downside of giving you no way to intercept the FIN/close.
-josh
|