How to let different processes use different network interfaces? - sockets

I'm on the client side. There're multiple network interfaces. How can I let different processes use different network interfaces to communicate? Since I want to connect to the same server, routing seems not working here. Also, connect() doesn't have arguments to specify local address or interface as bind() does.

If your goal is to increase bandwidth to the server by using multiple network interfaces in parallel, then that's probably not something you can (or should) do at the application level. Instead, you should study up on Link Aggregation and then configure your computer and networking stack to use that. Once that is working properly, you will get the parallelization-speedup you want automatically, without the client application having to do anything special to enable it.

"The bind() system call is frequently misunderstood. It is used to
bind to a particular IP address. Only packets destined to that IP
address will be received, and any transmitted packets will carry that
IP address as their source. bind() does not control anything about the
routing of transmitted packets. So for example, if you bound to the IP
address of eth0 but you send a packet to a destination where the
kernel's best route goes out eth1, it will happily send the packet out
eth1 with the source IP address of eth0. This is perfectly valid for
TCP/IP, where packets can traverse unrelated networks on their way to
the destination."
More info e.g. here.
That's why you probably misunderstand bind() call.
The appropriate way to bind to physical topology (to some specific interface) is to use SO_BINDTODEVICE socket option. This is done by setsockopt() call.

Source Policy Routing might be helpful.
Try the following steps:
Use iptables to give packets from different process with different marks.
Use iproute2 to route packets with different marks to different table.
In different table, set the default route to different uplink.
The whole process require certain amount of understanding about linux networking.
Here is an example shows how to route all traffic for a user through one specific uplink: http://www.niftiestsoftware.com/2011/08/28/making-all-network-traffic-for-a-linux-user-use-a-specific-network-interface/
You could try follow similar approach by running different process with different user and route traffic from one user to one uplink.
Also you could let processes communicate with the server with different port and mark the traffic by port.

Related

Difference between "tcp/socket" vs "tcp/ip"

What is the difference between a "tcp/socket" and "tcp/ip" connexion?
When you say that you use "tcp/ip", do you necessarily use a "tcp/socket"?
Thanks!
A socket is a general communication means provided by your
operating system.
There are many kinds of them, for very distinct purposes
(not only networking).
I guess that when you think about tcp/socket, you mean a
socket dedicated to the TCP protocol.
TCP/IP can be seen as two different things, depending on the context.
It can be the TCP/IP network stack as a whole: not only the TCP and IP
specific protocols but the set of protocols (and implementations) we
find around these.
Of course, the other way to see TCP/IP is to consider only the TCP
transport protocol relying on the IP network protocol.
The various operating systems implement many protocols
in the TCP/IP stack.
To use them, a programmer asks his/her operating system
a specific resource: a socket.
It's difficult to say more with few words.
Some books or online documentation could help go further.
I think you missing something in the question. Anyway in short...
TCP/IP is basically name given to protocol we (networking devices) follow it forms the fundamental of todays internet. It involves agreement between two devices how the want ro communicate eg. Which segment of a frame has what information as in the end its all just 10...
There are 5 layers (some argue 4) in this model one layer is Network Layer right at the middle of all and it generally uses IPv4.And just above this is our Transport Layer which may use TCP or UDP as protocol depending on service you want. So thats the summary of TCP/ IP as the most used set of protocols of all.
When connecting to a remote server your browser needs to know what kind of service he is about to get from that server eg. a video mail or file transfer or just a http page. Thats when a TCP/Socket comes into picture where there is a port no assigned for every service. Eg port 443 is for https and so on. All you need to do is open a socket connection over that port number on that machine
Remember if a particular port of a server is not in LISTEN mode you cannot connect to that application via that port
Eg. If a server serves its webpage it might not allow you to connect its port responsible for FTP.

How to use UDP from a machine with only NAT access

I have a machine, with no external IP address, it will need to send UDP packets to the outside world. Only NAT access.
Will this work?
It is really hard to prototype this in our environment.
It is still really under construction.
Any thoughts on how I can prototype this?
Most of the home network configurations in the world are made of a PC with an internal IP and a router with a public IP that NAT the internal one. (Independently of UDP/TCP or whatever protocol that needs to go out)
I see no troubles with it
It should work.
Ensure that for the socket created, set the TTL (time-to-live) to a value that is sufficiently large to cover the possible number of router hops to reach the destination. Running traceroute to the destination IP will give you a rough idea on the number of hops. Note that this value can change depending on network conditions. So it's best to set this to a larger value. Refer to sockets IOCtl API documentation for the syntax for setting TTL.
Finally, remember that UDP is not a reliable protocol. So even after taking the necessary steps above, the packet may not reach its destination. However, if the entire network, including the intermediary routers, is within a controlled environment, such as a corporate intranet, chances of packet drop are minimal.
If you want to add reliability on top of UDP, you can adopt a NAK based algorithm where packets are stamped with a sequence number. Various resources might advise you that if you need to add reliability over UDP you should consider TCP, but my experience has been that if your app runs in a controlled environment with very minimal chance of packet drops and you need fast connection setup and tear down, adding a lightweight reliability over UDP has its merits. Also TCP connections take up valuable space in the OS kernel whereas UDP don't. This could also be a consideration if you want to support very large number of 'connections' in a constrained environment.
At the end of the day you need to experiment a little to figure out what works best for you.
To prototype, I would set up a NAT server using something like Linux and then start working from there. Real world traffic scenarios that you want to simulate will determine where the client and server are to be located on either side of the NAT. That is, if the traffic should go through an ISP or all within a controlled environment.
HTH

Coordinating peer-to-peer messages using multicast, how to get receiving IP?

I have been working on a local LAN service which uses a multicast port to coordinate several machines. Each machine listens on the multicast port for instructions, and when a certain instruction is received, will send messages directly to other machines.
In other words the multicast port is used to coordinate peer-to-peer UDP messaging.
In practice this works quite well but there is a lingering issue related to correctly setting up these peer-to-peer transmissions. Basically, each machine needs to announce on the multicast port its own IP address, so that other machines know where to send messages when they wish to start a P2P transmission.
I realize that in general the idea of identifying the local IP is not necessarily sensible, but I don't see any other way-- the local receiving IP must be announced one way or another. At least I am not working on the internet, so in general I won't need to worry about NATs, just need to identify the local LAN IP. (No more than 1 hop for the multicast packets is allowed.)
I wanted to, if possible, determine the IP passively, i.e., without sending any messages.
I have been using code that calls getifaddrs(), which returns a linked list of NICs on the machine, and I scan this list for non-zero IP addresses and choose the first one.
In general this has worked okay, but we have had issues where for example a machine with both a wired and wifi connection are active, it will identify the wrong one, and the only work-around we found was to turn off the wifi.
Now, I imagine that a more reliable solution would be to send a message to the multicast telling other machines to report back with the source address of the message; that might allow to identify which IP is actually visible to the other machines on the net. Alternatively maybe even just looking at the multicast loopback message would work.
What do you think, are there any passive solutions to identify which address to use? If not, what's the best active solution?
I'm using POSIX socket API from C. Must work on Linux, OS X, Windows. (For Windows I have been using GetAdapterAddresses().)
Your question about how to get the address so you can advertise it right is looking at it from the wrong side. It's a losing proposition to try to guess what your address is. Better for the other side to detect it itself.
When a listening machine receives a message, it is probably doing do using recvfrom(2). The fifth argument is a buffer into which the kernel will store the address of the peer, if the underlying protocol offers it. Since you are using IP/UDP, the buffer should get filled in with a sockaddr_in showing the IP address of the sender.
I'd use the address on the interface I use to send the announcement multicast message -- on the wired interface announce the wired address and on the wireless interface announce the wireless address.
When all the receivers live on the wired side, they will never see the message on the wireless network.
When there is a bridge between the wired and the wireless network, add a second step in discovery for round-trip time estimation, and include a unique host ID in the announcement packet, so multiple routes to the same host can be detected and the best one chosen.
Also, it may be a good idea to add a configuration option to limit the service to certain interfaces.

SIP and NAT traversal

I'm trying to understand the exact problem with NAT and SIP and have seen many different explanations. Here's what I've gathered so far:
1) SIP User agent is both initiating and accepting calls, therefore unless the NAT/firewall is configured to accept incoming traffic on this port it cannot work - this makes sense but sounds more firewall and port mapping
2) SIP messages contain IP addresses (that can be private) in the body which requires NAT traversal - if this is the case
3) it's not a problem with SIP but with RTP, whose parameters that are included in the SDP as part of the SIP message body that include private IP addresses
4) something to do with UDP vs. TCP?
When a call is done with SIP the calling endpoing does not know the endpoint the call must reach i.e. the endpoint's IP.
It only knows the IP address of the SIP server.
So the INVITE goes to the SIP server and SIP servers "knows" where/how to reach the called endpoints.
The idea is that the SIP messages contain SDP data that contain the information needed so that eventually the phones will be able to set up a session and users will be able to start talking.
These data include IP, port, codecs and other parameters.
So if one of the phones is behind NAT the phone will report as its IP e.g. IP_X which is its private IP and the other endpoint can not reach that IP; the public IP is unknown at that point.
All of your assumptions are correct.
In SIP, you can split it into 2 main problems: signaling and media.
The signaling runs in SIP over either TCP or UDP, and the connection can open from both directions, as calls can be dialed or accepted by user agents.
The media runs over RTP (and RTCP), which is usually done over UDP (unless you're trying to achieve NAT traversal), and then it might go over TCP). The ports and addresses here are allocated dynamically, need to go both ways and run on multiple sessions (=multiple sockets and connections).
To achieve NAT traversal, you will usually use multiple techniques: STUN, TURN, ICE, HTTP tunneling and even an SBC.
NAT traversal for SIP requires external support from servers - usually not the SIP server - that are dedicated for the job.
I'll disagree mildly with Tsahi Levent-Levi's answer.
The problem is that the IP address you put in your Via, Contact, From/To headers, SDP, etc., must be globally routable. If you're behind a NAT you'll obviously need to put in your external IP address.
Implementing ICE, using STUN, etc., allows you to do this automatically, but you can always solve the program manually.
In particular, by inspecting your machine's routing table you can tell whether or not the machine you're calling is behind a NAT or not (by virtue of knowing that work machines are behind this VPN NAT here, and local machines are on this subnet, and everything else runs through your router's NAT). With that information you may find out a NAT's far-side/external address somehow (STUN gives this automatically, but your internet router may have a static address, or you could contact an HTTP server capable of returning your external address, or ...). Once you have that far-side/external address, you can put the address where necessary - your Contact header, SDP c= headers, and the like.
There is a whitepaper by Eyeball Networks that clearly explains the NAT & firewall traversal problem for voip and the STUN, TURN, ICE solution. There are also a couple of great diagrams on how SIP P2P and SIP TURN calls are achieved at http://www.eyeball.com/voip-solutions/stun-turn-ice.htm

UDP multicast from specific network card

I'm looking for some networking gurus to help me with a problem. I have many computers running my software which uses UDP multicasting. This works fine if the computers are connected ONLY to one network (network A). My computer (which is also running said software) will listen on port XXXX for the multicasts. This computer has two network cards and when I connect it to another network, network B, my software goes haywire. The problem is that I do not know what network a given multicast came from. And if I send out a multicast, I cannot tell it to use network A instead of network B or vice versa.
My questions:
Is there a way to distinguish packets coming in from different networks??
Is there a way to send a multicast to network A and NOT network B?
I'm using C++ and Win32 sockets. Thanks to anyone that replies.
You should listen for multicast packets on one interface where you joined the group. You should explicitly set the interface used for sending the multicast packets (otherwise they are routed as everything else, default route, etc.). Both are accomplished via setsockopt calls. Here are some links for you:
Multicast programming - talks about setting "send" interface,
IP Multicast Extensions - talks about both "send" and "receive" interfaces.
Disclaimer: the links are admittedly Unix-centric, so your Windows mileage may vary :)
Working on a project with MC UDP on redundant NICs over the last year, we saw a similar problem. After battling it a bit with winsock, our ultimate solution was to prioritize traffic using the DOS command route
route add 224.x.x.x ... [desired gateway] METRIC 1
This ensured that the traffic only went out on the Interface we wanted.
I realize this might not be exactly what you want, but it could at least be a stopgap solution while you implement another fix.
On multihomed hosts you need to join the multicast group via all interfaces sequentially, or via all the ones you care about. If you are interested in network of origin you could use multiple M/C sockets, each bound to a different interface, same port, and each of them joined to the group; then the receiving socket itself tells you which network any incoming traffic comes from.