Sto imparando C scrivendo una piccola applicazione che invia una query DNS a un server specificato. Ecco un esempio di codice di rete:Porta di origine e di destinazione per il socket UDP?
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));
}
Questo funziona bene come la query viene inviata con successo, e una risposta è ricevuto. Tuttavia, annusando il traffico con Wireshark posso vedere il messaggio: Destination unreachable (Port unreachable)
.
ho scoperto che posso evitare questo chiamando bind()
prima 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));
}
Ora il messaggio Destination unreachable (Port unreachable)
è andato, ma l'applicazione deve essere eseguito con i privilegi di root in quanto si legherà alla porta 53.
È possibile modificare il codice in modo da utilizzare una porta di origine casuale non privilegiata?
Problema risolto
Il problema si è verificato a causa di un errore stupido. Ho semplicemente commentato recvfrom()
. Mentre stavo annusando il traffico durante il test dell'applicazione, ho potuto vedere la risposta e l'errore verificatosi sul mio computer e ho confuso erroneamente questo dato che l'applicazione stava recuperando. Perché non so cosa diavolo sto facendo, ho iniziato a scherzare con bind()
ecc. E questa valanga di insuccessi è iniziata.
Per brevità non ho pubblicato tutto il codice, ma il problema era stato probabilmente risolto immediatamente se lo avessi fatto.
Sei sicuro che una porta di origine casuale non sia già utilizzata? – Xaqq
Bene, potresti eseguire Math in modo casuale per i numeri superiori a 1024 e al di sotto del limite, ma potresti accidentalmente ottenere una porta che è già in uso, quindi è necessario implementare la logica per gestirla. –
@MatthewHerbst Si potrebbe fare un ciclo mentre 'bind()' fallisce. Comunque non mi preoccuperei. Credo che questo messaggio "Destinazione irraggiungibile (Port non raggiungibile)" sia innocuo. – Xaqq