I am learning C, writing a small application that sends a DNS query to a specified server. The following is an example of network code:
int send_query() { int sockfd; struct sockaddr_in server; if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { perror("cannot create socket\n"); } memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(53); inet_pton(AF_INET, "8.8.8.8", &(server.sin_addr)); sendto(sockfd, const void *buffer, size_t length, 0, (struct sockaddr *) &server, sizeof(server)); }
This works fine as the request is sent successfully and a response is received. However, sniffing traffic with Wireshark, I see a message: Destination unreachable (Port unreachable) .
I found out that I can avoid this by calling bind() before sendto() :
int send_query() { int sockfd; struct sockaddr_in server; if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { perror("cannot create socket\n"); } memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(53); inet_pton(AF_INET, "8.8.8.8", &(server.sin_addr)); if(bind(sockfd, (struct sockaddr *) &server, sizeof(server)) < 0) { perror("bind failed\n"); } sendto(sockfd, const void *buffer, size_t length, 0, (struct sockaddr *) &server, sizeof(server)); }
Now the message Destination unreachable (Port unreachable) has disappeared, but the application must be running as root, as it will bind to port 53.
Is it possible to change the code to use a random unprivileged source port instead?
Problem solved
The problem arose due to a stupid error. I just commented on recvfrom() . When I sniffed traffic while testing the application, I could see the answer and error that occur on my computer, and mistakenly confused this, because the application was receiving. Since I don't know what the hell I am doing, I started messing around with bind() , etc., And this avalanche of failure began.
For brevity, I did not publish all the code, but the problem was probably resolved immediately if this happened.