Search code examples
clinuxsocketsnetwork-programmingicmp

Linux multiple ICMP sockets


I'm an absolute novice of networking in Linux. In particular I was looking some example of ICMP protocol in particular I was looking at ping requests and replies. Usually all start by opening a raw socket

int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

and then there is something like (sketchy code)

while (1) {
   sendto(sockfd, ...);
   usleep(CERTAIN_TIME);
   recvfrom(sockfd, ...);
   // then the reply is elaborated
}

I was wandering if it is also possible to open two of these raw sockets: one just used with sendto, the other used with recvfrom and use them by two different threads:

// initialization
int sendsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
int recvsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

then

// thread 1
while (1) {
   sendto(sendsock, ...);
   usleep(CERTAIN_TIME);
}

// thread 2
while (1) {
   recvfrom(recvsock, ...);
   usleeep(CERTAIN_TIME);
}

Is it safe?


Solution

  • Since the ICMP protocol is connectionless and there are no port numbers to bind ti, all ICMP sockets are essentially equivalent. Multiple sockets in the same process are no different from sockets in different processes. Calling recvfrom() on any of them will return any incoming ICMP packets.

    You can optionally call connect() on an ICMP socket, to specify a remote address. In that case, you can use call send() rather than sendto(), and it will send only to that address. And you can call recv() and it will only return packets that come from that remote address. This will make some those sockets not equivalent to unconnected sockets or sockets connected to a different address. But if you're pinging the same address, you could still use two sockets that are each connected to that address, one for sending and the other for receiving.

    But there's no benefit from using separate sockets for the two directions. Sockets are inherently thread-safe.