c - sockaddr value changes unexpectedly after calling getaddrinfo() -


i programming udp client. want bind socket given port on client machine, same port used sends. sockaddr server using getaddrinfo, , same sockaddr pass call getaddrinfo. however, after second call getaddrinfo address of server machine changes, , end sending packet client machine client machine itself.

the following code standalone example reproduces error:

#include <stdio.h> #include <stdint.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h>  #define server_host "www.google.com" #define udp_port "4000"  static struct sockaddr_in *destination_addr = null; static int client_port;  int main(){      uint8_t bytes[5] = { 0xaa, 0xab, 0xac, 0xad, 0xaf}; //some data send      uint16_t length = 5;     int status;       //initialize socket , bind     if (destination_addr == null) {         struct addrinfo hints;         struct addrinfo *servinfo, *p;         srand(time(null));         memset(&hints, 0, sizeof hints);         hints.ai_family = af_inet;         hints.ai_socktype = sock_dgram;         hints.ai_flags = ai_passive;          if ((status = getaddrinfo(server_host, udp_port, &hints, &servinfo)) != 0) {             printf("unable send udp. reason: %s", gai_strerror(status));             return 0;         }           (p = servinfo; p != null; p = p->ai_next) {             if (p->ai_addr != null)                 destination_addr = (struct sockaddr_in *) p->ai_addr;         }         client_port = 1027 + rand()%50000;         freeaddrinfo(servinfo);         printf("created destination_addr ip %s\n",  inet_ntoa(destination_addr->sin_addr));     }       int send_socket_fd = socket(af_inet, sock_dgram, 0);     if (send_socket_fd == -1) {         printf("unable create udp socket. reason: %s", strerror(errno));         return 0;     }     printf("ip after socket creation %s\n", inet_ntoa(destination_addr->sin_addr));     int yes = 1;     if (setsockopt(send_socket_fd, sol_socket, so_reuseaddr, &yes, sizeof (int)) == -1) {         perror("setsockopt");         return 0;     }     printf("ip after sockopt %s\n", inet_ntoa(destination_addr->sin_addr));      // bind local address     char str_client_port[6];     snprintf(str_client_port, 5, "%d", client_port);     struct addrinfo *source_addr_info;     struct addrinfo hints;     hints.ai_family = af_inet;     hints.ai_socktype = sock_dgram;       // ***** destination_addr changes after call *****     getaddrinfo (null, str_client_port, &hints, &source_addr_info);        printf("ip after getaddrinfo %s\n", inet_ntoa(destination_addr->sin_addr));     bind(send_socket_fd, source_addr_info->ai_addr, source_addr_info->ai_addrlen);     printf("ip after binding %s\n", inet_ntoa(destination_addr->sin_addr));      // send     int bytes_sent = sendto(send_socket_fd, bytes, length, 0, (struct sockaddr *)destination_addr, sizeof *destination_addr);     printf("sent ip %s\n", inet_ntoa(destination_addr->sin_addr));     if (bytes_sent != length){         if (bytes_sent == -1){             printf("udp send failed. reason: %s", strerror(errno));         }         else {             printf("udp: not bytes sent.");         }     }       close(send_socket_fd);     return 1;  } 

the output generated execution of program in machine is:

created destination_addr ip 64.233.167.105 ip after socket creation 64.233.167.105 ip after sockopt 64.233.167.105 ip after getaddrinfo 0.0.0.0 ip after binding 0.0.0.0 sent ip 0.0.0.0 

i rather new socket programming in c, , pretty sure doing silly mistake, after googling lot , trying many things, still stuck this. idea?

solved. @molbdnilo pointed out, error caused call freeaddrinfo. fix copy value pointed p->ai_addr, not lost when freeing. substituted:

if (p->ai_addr != null)     destination_addr = (struct sockaddr_in *) p->ai_addr; 

with

if (p->ai_addr != null){     destination_addr = malloc(sizeof *destination_addr);     memcpy(destination_addr, (struct sockaddr_in *)p->ai_addr, sizeof *p->ai_addr); } 

and worked.


Comments

Popular posts from this blog

html - Outlook 2010 Anchor (url/address/link) -

javascript - Why does running this loop 9 times take 100x longer than running it 8 times? -

Getting gateway time-out Rails app with Nginx + Puma running on Digital Ocean -