Hesitation regarding getaddrinfo () correct usage for handling IPV4 and IPV6

I am trying to write an IP address class that handles IPV6 and IPV4 addresses; I am using the sockadrr_storage data structure to achieve this. I've already written most of this class, but now I'm having difficulty creating an interface that uses the getaddrinfo () function in a smart and correct way. I want to create a constructor that can give and insert the correct IP address into the sockadrr_storage data structure after I have placed the parameter set. Some examples:

  • ip_address ip_v4 ("127.0.0.1"); β†’ This will give the feedback address
  • ip_address ip_v6 ("::", 0, AF_INET6, SOCK_STREAM); -> This will give a V6 link locally
  • ip_address host_adr ("www.google.it"); -> This will take a look at the dns

To do this, this function must make a call to getaddrrinfo () with the correct parameters. I have to handle these cases:

  • loopback V4 and V6
  • wildcard V4 and V6
  • numeric string V4 and V6
  • hostname string V4 and V6

There is some code here that I have written so far.

bool ip_address::parse_addr(std::string addr_ , std::string port_ , int ai_family , int ai_socktype)
{

  struct addrinfo hints , * host_info ;
  memset(&hints , 0, sizeof(struct addrinfo));

  switch(ai_family)
  {
    case AF_INET:
      hints.ai_family = AF_INET;
      hints.ai_socktype = ai_socktype;
      break;

    case AF_INET6:
      hints.ai_family = AF_INET6;
      hints.ai_socktype = ai_socktype;
      break;
  }

  getaddrinfo(addr_.c_str(), port_.c_str(), &hints, &host_info);

  if(host_info->ai_family == AF_INET )
  {
    struct sockaddr_in adr;
    memset(&adr,0,sizeof(struct sockaddr_in));
    adr.sin_family = AF_INET;
    size_ = sizeof(struct sockaddr_in);
    address_.ss_family = AF_INET;
    ((struct sockaddr_in *)&address_)->sin_addr = ((struct sockaddr_in *) host_info->ai_addr)->sin_addr;
  }
  else if(host_info->ai_family == AF_INET6 )
  {
    struct sockaddr_in6 adr;
    memset(&adr,0,sizeof(struct sockaddr_in6));
    adr.sin6_family = AF_INET6;
    size_ = sizeof(struct sockaddr_in6);
    address_.ss_family = AF_INET6;
    ((struct sockaddr_in6 *)&address_)->sin6_addr = ((struct sockaddr_in6 *) host_info->ai_addr)->sin6_addr;
  }

  freeaddrinfo(host_info);


return false;

      

parse_addr () is a method that is called from the constructor of the ip_address class .

Currently, this code only works for IPV4. In fact, when I add this call ip_address ip_v6("::", 0 , AF_INET6 , SOCK_STREAM);

to main (), it gives a Segmentation fault .

Do you see something wrong in this code?

Then I have a more general question: Could this be a smart solution to solve this problem? If you have any suggestions please let me know.

Many thanks.

+3


source to share





All Articles