C addrinfo struct gets corrupted. But heap is still valid












2















I try to create a socket and connect to a remote host. I resolve the remote host from domain with GetAddrInfo. Which works fine. After the call i get a working addrinfo struct with the right values. But in some situations the struct gets corrupted before calling connect().



struct addrinfoW sa = { 0 };
ZeroMemory(&sa, sizeof(sa));
lookup_host(host, &sa);

int sock = 0;
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == -1) {
return -1;
}
HeapValidate(GetProcessHeap(), HEAP_NO_SERIALIZE, NULL);
if(connect(sock, sa->ai_addr, sa->ai_addrlen) < 0) {
HeapValidate(GetProcessHeap(), HEAP_NO_SERIALIZE, NULL);
#ifdef _DEBUG
printf("Error: %dn", GetLastError());
#endif // _DEBUG

return -2;
}


Where lookup_host is defined as:



struct addrinfoW hints = { 0 };
struct addrinfoW *res;
int errcode;
ZeroMemory(&hints, sizeof(struct addrinfoW));
//ZeroMemory(res, sizeof(struct addrinfo));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags |= AI_CANONNAME;
errcode = GetAddrInfo(host, L"80", &hints, &res);//GetAddrInfoExW(L"google.de", L"80", NS_ALL, NULL, &hints, &res, NULL, NULL, NULL, NULL); //GetAddrInfoEX(L"google.de", L"80", &hints, &res);
win_free(mbHost);
if (errcode != 0)
{
//perror("getaddrinfo");
return -1;
}
void *ptr = 0;
while (res)
{
switch (res->ai_family)
{
case AF_INET:
ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
break;
case AF_INET6:
ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
break;
}
CopyMemory(out, res, sizeof(struct addrinfoW));
break;
res = res->ai_next;
}
FreeAddrInfo(res);


So this works well on my Quad-Core Win10 laptop. But if i add for example a



MessageBoxA(NULL, "After sock", "HTTP", MB_ICONWARNING|MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);


call before the connect() call and examine the addrinfo struct in debugger it gets corrupted. For example some time i can see that the ai_canonname which should be "google.com" get overwritten with "After Sock". But the heap is still valid after that.
So i have no idea where to start debugging this. Could it be some other buffer or struct which overflows somewhere?










share|improve this question



























    2















    I try to create a socket and connect to a remote host. I resolve the remote host from domain with GetAddrInfo. Which works fine. After the call i get a working addrinfo struct with the right values. But in some situations the struct gets corrupted before calling connect().



    struct addrinfoW sa = { 0 };
    ZeroMemory(&sa, sizeof(sa));
    lookup_host(host, &sa);

    int sock = 0;
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock == -1) {
    return -1;
    }
    HeapValidate(GetProcessHeap(), HEAP_NO_SERIALIZE, NULL);
    if(connect(sock, sa->ai_addr, sa->ai_addrlen) < 0) {
    HeapValidate(GetProcessHeap(), HEAP_NO_SERIALIZE, NULL);
    #ifdef _DEBUG
    printf("Error: %dn", GetLastError());
    #endif // _DEBUG

    return -2;
    }


    Where lookup_host is defined as:



    struct addrinfoW hints = { 0 };
    struct addrinfoW *res;
    int errcode;
    ZeroMemory(&hints, sizeof(struct addrinfoW));
    //ZeroMemory(res, sizeof(struct addrinfo));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags |= AI_CANONNAME;
    errcode = GetAddrInfo(host, L"80", &hints, &res);//GetAddrInfoExW(L"google.de", L"80", NS_ALL, NULL, &hints, &res, NULL, NULL, NULL, NULL); //GetAddrInfoEX(L"google.de", L"80", &hints, &res);
    win_free(mbHost);
    if (errcode != 0)
    {
    //perror("getaddrinfo");
    return -1;
    }
    void *ptr = 0;
    while (res)
    {
    switch (res->ai_family)
    {
    case AF_INET:
    ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
    break;
    case AF_INET6:
    ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
    break;
    }
    CopyMemory(out, res, sizeof(struct addrinfoW));
    break;
    res = res->ai_next;
    }
    FreeAddrInfo(res);


    So this works well on my Quad-Core Win10 laptop. But if i add for example a



    MessageBoxA(NULL, "After sock", "HTTP", MB_ICONWARNING|MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);


    call before the connect() call and examine the addrinfo struct in debugger it gets corrupted. For example some time i can see that the ai_canonname which should be "google.com" get overwritten with "After Sock". But the heap is still valid after that.
    So i have no idea where to start debugging this. Could it be some other buffer or struct which overflows somewhere?










    share|improve this question

























      2












      2








      2








      I try to create a socket and connect to a remote host. I resolve the remote host from domain with GetAddrInfo. Which works fine. After the call i get a working addrinfo struct with the right values. But in some situations the struct gets corrupted before calling connect().



      struct addrinfoW sa = { 0 };
      ZeroMemory(&sa, sizeof(sa));
      lookup_host(host, &sa);

      int sock = 0;
      sock = socket(AF_INET, SOCK_STREAM, 0);
      if(sock == -1) {
      return -1;
      }
      HeapValidate(GetProcessHeap(), HEAP_NO_SERIALIZE, NULL);
      if(connect(sock, sa->ai_addr, sa->ai_addrlen) < 0) {
      HeapValidate(GetProcessHeap(), HEAP_NO_SERIALIZE, NULL);
      #ifdef _DEBUG
      printf("Error: %dn", GetLastError());
      #endif // _DEBUG

      return -2;
      }


      Where lookup_host is defined as:



      struct addrinfoW hints = { 0 };
      struct addrinfoW *res;
      int errcode;
      ZeroMemory(&hints, sizeof(struct addrinfoW));
      //ZeroMemory(res, sizeof(struct addrinfo));
      hints.ai_family = PF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_flags |= AI_CANONNAME;
      errcode = GetAddrInfo(host, L"80", &hints, &res);//GetAddrInfoExW(L"google.de", L"80", NS_ALL, NULL, &hints, &res, NULL, NULL, NULL, NULL); //GetAddrInfoEX(L"google.de", L"80", &hints, &res);
      win_free(mbHost);
      if (errcode != 0)
      {
      //perror("getaddrinfo");
      return -1;
      }
      void *ptr = 0;
      while (res)
      {
      switch (res->ai_family)
      {
      case AF_INET:
      ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
      break;
      case AF_INET6:
      ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
      break;
      }
      CopyMemory(out, res, sizeof(struct addrinfoW));
      break;
      res = res->ai_next;
      }
      FreeAddrInfo(res);


      So this works well on my Quad-Core Win10 laptop. But if i add for example a



      MessageBoxA(NULL, "After sock", "HTTP", MB_ICONWARNING|MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);


      call before the connect() call and examine the addrinfo struct in debugger it gets corrupted. For example some time i can see that the ai_canonname which should be "google.com" get overwritten with "After Sock". But the heap is still valid after that.
      So i have no idea where to start debugging this. Could it be some other buffer or struct which overflows somewhere?










      share|improve this question














      I try to create a socket and connect to a remote host. I resolve the remote host from domain with GetAddrInfo. Which works fine. After the call i get a working addrinfo struct with the right values. But in some situations the struct gets corrupted before calling connect().



      struct addrinfoW sa = { 0 };
      ZeroMemory(&sa, sizeof(sa));
      lookup_host(host, &sa);

      int sock = 0;
      sock = socket(AF_INET, SOCK_STREAM, 0);
      if(sock == -1) {
      return -1;
      }
      HeapValidate(GetProcessHeap(), HEAP_NO_SERIALIZE, NULL);
      if(connect(sock, sa->ai_addr, sa->ai_addrlen) < 0) {
      HeapValidate(GetProcessHeap(), HEAP_NO_SERIALIZE, NULL);
      #ifdef _DEBUG
      printf("Error: %dn", GetLastError());
      #endif // _DEBUG

      return -2;
      }


      Where lookup_host is defined as:



      struct addrinfoW hints = { 0 };
      struct addrinfoW *res;
      int errcode;
      ZeroMemory(&hints, sizeof(struct addrinfoW));
      //ZeroMemory(res, sizeof(struct addrinfo));
      hints.ai_family = PF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_flags |= AI_CANONNAME;
      errcode = GetAddrInfo(host, L"80", &hints, &res);//GetAddrInfoExW(L"google.de", L"80", NS_ALL, NULL, &hints, &res, NULL, NULL, NULL, NULL); //GetAddrInfoEX(L"google.de", L"80", &hints, &res);
      win_free(mbHost);
      if (errcode != 0)
      {
      //perror("getaddrinfo");
      return -1;
      }
      void *ptr = 0;
      while (res)
      {
      switch (res->ai_family)
      {
      case AF_INET:
      ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
      break;
      case AF_INET6:
      ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
      break;
      }
      CopyMemory(out, res, sizeof(struct addrinfoW));
      break;
      res = res->ai_next;
      }
      FreeAddrInfo(res);


      So this works well on my Quad-Core Win10 laptop. But if i add for example a



      MessageBoxA(NULL, "After sock", "HTTP", MB_ICONWARNING|MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);


      call before the connect() call and examine the addrinfo struct in debugger it gets corrupted. For example some time i can see that the ai_canonname which should be "google.com" get overwritten with "After Sock". But the heap is still valid after that.
      So i have no idea where to start debugging this. Could it be some other buffer or struct which overflows somewhere?







      c winsock memory-corruption






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 14 '18 at 12:48









      mannermanner

      183




      183
























          3 Answers
          3






          active

          oldest

          votes


















          0














          It's because you free all the memory associated with the results before you use it. For example ai_canonname is a pointer to a string that is allocated from the heap. The memory containing its bytes is flagged as free for reuse before you exit lookup_host. Your CopyMemory will copy the pointer but not the bytes it points to.



          NB you should post the whole of lookup_host including the function definition.



          You need to find a way of avoiding the call to FreeAddrInfo until after you are done. Either that or do a deeper copy of the struct including all the things being pointed to which you will find rapidly turns into a rabbit hole.



          The way I would do it is to provide a callback function that is called while inside lookup_host






          share|improve this answer































            0














            your while (res) is moving the pointer res to other nodes other the origibal one each time you execute line res = res->ai_next;, but then you call FreeAddrInfo(res); at the end with modified pointer, not the one allocated via GetAddrInfo.



            Also, although you don't provide the start of the lookup_host function, but assuming an inout is ptr, you are setting it to the address of sin_addr from the allocated emory, and then freeing the memory at the end of the function, so it may be used by something else.






            share|improve this answer































              0














              Your lookup_host() is not returning address data back to the caller correctly, not even close. addrinfo contains pointers to data outside of the addrinfo. But you are just copying the addrinfo itself to the caller, but none of the data it points at.



              Try something more like this instead:



              int lookup_host(const wchar_t *host, int family, void *sa)
              {
              struct addrinfoW hints;
              struct addrinfoW *res, *addr;
              int errcode, addrlen, returnval;
              void *ptr;

              ZeroMemory(&hints, sizeof(hints));
              hints.ai_family = family;
              hints.ai_socktype = SOCK_STREAM;

              errcode = GetAddrInfoW(host, L"80", &hints, &res);
              //GetAddrInfoExW(host, L"80", NS_ALL, NULL, &hints, &res, NULL, NULL, NULL, NULL);
              if (errcode != 0)
              {
              //perror("getaddrinfo");
              return -1;
              }

              returnval = 0;

              for(addr = res; addr != NULL; addr = addr->ai_next)
              {
              switch (addr->ai_family)
              {
              case AF_INET:
              ptr = &((struct sockaddr_in *) addr->ai_addr)->sin_addr;
              addrlen = sizeof(struct sockaddr_in);
              break;

              case AF_INET6:
              ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
              addrlen = sizeof(struct sockaddr_in6);
              break;

              default:
              continue;
              }

              CopyMemory(sa, ptr, addrlen);
              returnval = 1;
              break;
              }

              FreeAddrInfoW(res);

              return returnval;
              }

              ...

              struct sockaddr_in sa;

              if (lookup_host(host, AF_INET, &sa) != 1) {
              return -1;
              }

              SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
              if (sock == INVALID_SOCKET) {
              return -1;
              }

              if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
              #ifdef _DEBUG
              printf("Error: %dn", GetLastError());
              #endif // _DEBUG

              closesocket(sock);
              return -2;
              }

              ...


              Note, however, that the above returns only the first address found. A hostname can resolve to multiple IPs, and your PC might not have a route to all of them. So, you should attempt to connect to every address reported until one is successful, eg:



              int lookup_host(const wchar_t *host, int family, struct addrinfoW **addrs)
              {
              struct addrinfoW hints;
              int errcode;

              ZeroMemory(&hints, sizeof(hints));
              hints.ai_family = family;
              hints.ai_socktype = SOCK_STREAM;

              errcode = GetAddrInfoW(host, L"80", &hints, addrs);
              //GetAddrInfoExW(host, L"80", NS_ALL, NULL, &hints, addrs, NULL, NULL, NULL, NULL);
              if (errcode != 0)
              {
              //perror("getaddrinfo");
              return -1;
              }

              return 0;
              }

              ...

              struct addrInfoW *res, *addr;

              if (lookup_host(host, AF_INET, &res) < 0) { // or AF_INET6, or AF_UNSPEC
              return -1;
              }

              sock = INVALID_SOCKET;

              for(addr = res; addr != NULL; addr = addr->ai_next)
              {
              sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
              if (sock == INVALID_SOCKET) {
              break;
              }

              if (connect(sock, addr->ai_addr, addr->ai_addrlen) == 0) {
              break;
              }

              #ifdef _DEBUG
              printf("Error: %dn", GetLastError());
              #endif // _DEBUG

              closesocket(sock);
              sock = INVALID_SOCKET;
              }

              FreeAddrInfoW(res);

              if (sock == INVALID_SOCKET) {
              return -2;
              }

              ...





              share|improve this answer

























                Your Answer






                StackExchange.ifUsing("editor", function () {
                StackExchange.using("externalEditor", function () {
                StackExchange.using("snippets", function () {
                StackExchange.snippets.init();
                });
                });
                }, "code-snippets");

                StackExchange.ready(function() {
                var channelOptions = {
                tags: "".split(" "),
                id: "1"
                };
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function() {
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled) {
                StackExchange.using("snippets", function() {
                createEditor();
                });
                }
                else {
                createEditor();
                }
                });

                function createEditor() {
                StackExchange.prepareEditor({
                heartbeatType: 'answer',
                autoActivateHeartbeat: false,
                convertImagesToLinks: true,
                noModals: true,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: 10,
                bindNavPrevention: true,
                postfix: "",
                imageUploader: {
                brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                allowUrls: true
                },
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                });


                }
                });














                draft saved

                draft discarded


















                StackExchange.ready(
                function () {
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53300622%2fc-addrinfo-struct-gets-corrupted-but-heap-is-still-valid%23new-answer', 'question_page');
                }
                );

                Post as a guest















                Required, but never shown

























                3 Answers
                3






                active

                oldest

                votes








                3 Answers
                3






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes









                0














                It's because you free all the memory associated with the results before you use it. For example ai_canonname is a pointer to a string that is allocated from the heap. The memory containing its bytes is flagged as free for reuse before you exit lookup_host. Your CopyMemory will copy the pointer but not the bytes it points to.



                NB you should post the whole of lookup_host including the function definition.



                You need to find a way of avoiding the call to FreeAddrInfo until after you are done. Either that or do a deeper copy of the struct including all the things being pointed to which you will find rapidly turns into a rabbit hole.



                The way I would do it is to provide a callback function that is called while inside lookup_host






                share|improve this answer




























                  0














                  It's because you free all the memory associated with the results before you use it. For example ai_canonname is a pointer to a string that is allocated from the heap. The memory containing its bytes is flagged as free for reuse before you exit lookup_host. Your CopyMemory will copy the pointer but not the bytes it points to.



                  NB you should post the whole of lookup_host including the function definition.



                  You need to find a way of avoiding the call to FreeAddrInfo until after you are done. Either that or do a deeper copy of the struct including all the things being pointed to which you will find rapidly turns into a rabbit hole.



                  The way I would do it is to provide a callback function that is called while inside lookup_host






                  share|improve this answer


























                    0












                    0








                    0







                    It's because you free all the memory associated with the results before you use it. For example ai_canonname is a pointer to a string that is allocated from the heap. The memory containing its bytes is flagged as free for reuse before you exit lookup_host. Your CopyMemory will copy the pointer but not the bytes it points to.



                    NB you should post the whole of lookup_host including the function definition.



                    You need to find a way of avoiding the call to FreeAddrInfo until after you are done. Either that or do a deeper copy of the struct including all the things being pointed to which you will find rapidly turns into a rabbit hole.



                    The way I would do it is to provide a callback function that is called while inside lookup_host






                    share|improve this answer













                    It's because you free all the memory associated with the results before you use it. For example ai_canonname is a pointer to a string that is allocated from the heap. The memory containing its bytes is flagged as free for reuse before you exit lookup_host. Your CopyMemory will copy the pointer but not the bytes it points to.



                    NB you should post the whole of lookup_host including the function definition.



                    You need to find a way of avoiding the call to FreeAddrInfo until after you are done. Either that or do a deeper copy of the struct including all the things being pointed to which you will find rapidly turns into a rabbit hole.



                    The way I would do it is to provide a callback function that is called while inside lookup_host







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 14 '18 at 13:07









                    JeremyPJeremyP

                    74.4k13107145




                    74.4k13107145

























                        0














                        your while (res) is moving the pointer res to other nodes other the origibal one each time you execute line res = res->ai_next;, but then you call FreeAddrInfo(res); at the end with modified pointer, not the one allocated via GetAddrInfo.



                        Also, although you don't provide the start of the lookup_host function, but assuming an inout is ptr, you are setting it to the address of sin_addr from the allocated emory, and then freeing the memory at the end of the function, so it may be used by something else.






                        share|improve this answer




























                          0














                          your while (res) is moving the pointer res to other nodes other the origibal one each time you execute line res = res->ai_next;, but then you call FreeAddrInfo(res); at the end with modified pointer, not the one allocated via GetAddrInfo.



                          Also, although you don't provide the start of the lookup_host function, but assuming an inout is ptr, you are setting it to the address of sin_addr from the allocated emory, and then freeing the memory at the end of the function, so it may be used by something else.






                          share|improve this answer


























                            0












                            0








                            0







                            your while (res) is moving the pointer res to other nodes other the origibal one each time you execute line res = res->ai_next;, but then you call FreeAddrInfo(res); at the end with modified pointer, not the one allocated via GetAddrInfo.



                            Also, although you don't provide the start of the lookup_host function, but assuming an inout is ptr, you are setting it to the address of sin_addr from the allocated emory, and then freeing the memory at the end of the function, so it may be used by something else.






                            share|improve this answer













                            your while (res) is moving the pointer res to other nodes other the origibal one each time you execute line res = res->ai_next;, but then you call FreeAddrInfo(res); at the end with modified pointer, not the one allocated via GetAddrInfo.



                            Also, although you don't provide the start of the lookup_host function, but assuming an inout is ptr, you are setting it to the address of sin_addr from the allocated emory, and then freeing the memory at the end of the function, so it may be used by something else.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 14 '18 at 13:06









                            lostbardlostbard

                            3,1031311




                            3,1031311























                                0














                                Your lookup_host() is not returning address data back to the caller correctly, not even close. addrinfo contains pointers to data outside of the addrinfo. But you are just copying the addrinfo itself to the caller, but none of the data it points at.



                                Try something more like this instead:



                                int lookup_host(const wchar_t *host, int family, void *sa)
                                {
                                struct addrinfoW hints;
                                struct addrinfoW *res, *addr;
                                int errcode, addrlen, returnval;
                                void *ptr;

                                ZeroMemory(&hints, sizeof(hints));
                                hints.ai_family = family;
                                hints.ai_socktype = SOCK_STREAM;

                                errcode = GetAddrInfoW(host, L"80", &hints, &res);
                                //GetAddrInfoExW(host, L"80", NS_ALL, NULL, &hints, &res, NULL, NULL, NULL, NULL);
                                if (errcode != 0)
                                {
                                //perror("getaddrinfo");
                                return -1;
                                }

                                returnval = 0;

                                for(addr = res; addr != NULL; addr = addr->ai_next)
                                {
                                switch (addr->ai_family)
                                {
                                case AF_INET:
                                ptr = &((struct sockaddr_in *) addr->ai_addr)->sin_addr;
                                addrlen = sizeof(struct sockaddr_in);
                                break;

                                case AF_INET6:
                                ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
                                addrlen = sizeof(struct sockaddr_in6);
                                break;

                                default:
                                continue;
                                }

                                CopyMemory(sa, ptr, addrlen);
                                returnval = 1;
                                break;
                                }

                                FreeAddrInfoW(res);

                                return returnval;
                                }

                                ...

                                struct sockaddr_in sa;

                                if (lookup_host(host, AF_INET, &sa) != 1) {
                                return -1;
                                }

                                SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
                                if (sock == INVALID_SOCKET) {
                                return -1;
                                }

                                if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
                                #ifdef _DEBUG
                                printf("Error: %dn", GetLastError());
                                #endif // _DEBUG

                                closesocket(sock);
                                return -2;
                                }

                                ...


                                Note, however, that the above returns only the first address found. A hostname can resolve to multiple IPs, and your PC might not have a route to all of them. So, you should attempt to connect to every address reported until one is successful, eg:



                                int lookup_host(const wchar_t *host, int family, struct addrinfoW **addrs)
                                {
                                struct addrinfoW hints;
                                int errcode;

                                ZeroMemory(&hints, sizeof(hints));
                                hints.ai_family = family;
                                hints.ai_socktype = SOCK_STREAM;

                                errcode = GetAddrInfoW(host, L"80", &hints, addrs);
                                //GetAddrInfoExW(host, L"80", NS_ALL, NULL, &hints, addrs, NULL, NULL, NULL, NULL);
                                if (errcode != 0)
                                {
                                //perror("getaddrinfo");
                                return -1;
                                }

                                return 0;
                                }

                                ...

                                struct addrInfoW *res, *addr;

                                if (lookup_host(host, AF_INET, &res) < 0) { // or AF_INET6, or AF_UNSPEC
                                return -1;
                                }

                                sock = INVALID_SOCKET;

                                for(addr = res; addr != NULL; addr = addr->ai_next)
                                {
                                sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
                                if (sock == INVALID_SOCKET) {
                                break;
                                }

                                if (connect(sock, addr->ai_addr, addr->ai_addrlen) == 0) {
                                break;
                                }

                                #ifdef _DEBUG
                                printf("Error: %dn", GetLastError());
                                #endif // _DEBUG

                                closesocket(sock);
                                sock = INVALID_SOCKET;
                                }

                                FreeAddrInfoW(res);

                                if (sock == INVALID_SOCKET) {
                                return -2;
                                }

                                ...





                                share|improve this answer






























                                  0














                                  Your lookup_host() is not returning address data back to the caller correctly, not even close. addrinfo contains pointers to data outside of the addrinfo. But you are just copying the addrinfo itself to the caller, but none of the data it points at.



                                  Try something more like this instead:



                                  int lookup_host(const wchar_t *host, int family, void *sa)
                                  {
                                  struct addrinfoW hints;
                                  struct addrinfoW *res, *addr;
                                  int errcode, addrlen, returnval;
                                  void *ptr;

                                  ZeroMemory(&hints, sizeof(hints));
                                  hints.ai_family = family;
                                  hints.ai_socktype = SOCK_STREAM;

                                  errcode = GetAddrInfoW(host, L"80", &hints, &res);
                                  //GetAddrInfoExW(host, L"80", NS_ALL, NULL, &hints, &res, NULL, NULL, NULL, NULL);
                                  if (errcode != 0)
                                  {
                                  //perror("getaddrinfo");
                                  return -1;
                                  }

                                  returnval = 0;

                                  for(addr = res; addr != NULL; addr = addr->ai_next)
                                  {
                                  switch (addr->ai_family)
                                  {
                                  case AF_INET:
                                  ptr = &((struct sockaddr_in *) addr->ai_addr)->sin_addr;
                                  addrlen = sizeof(struct sockaddr_in);
                                  break;

                                  case AF_INET6:
                                  ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
                                  addrlen = sizeof(struct sockaddr_in6);
                                  break;

                                  default:
                                  continue;
                                  }

                                  CopyMemory(sa, ptr, addrlen);
                                  returnval = 1;
                                  break;
                                  }

                                  FreeAddrInfoW(res);

                                  return returnval;
                                  }

                                  ...

                                  struct sockaddr_in sa;

                                  if (lookup_host(host, AF_INET, &sa) != 1) {
                                  return -1;
                                  }

                                  SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
                                  if (sock == INVALID_SOCKET) {
                                  return -1;
                                  }

                                  if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
                                  #ifdef _DEBUG
                                  printf("Error: %dn", GetLastError());
                                  #endif // _DEBUG

                                  closesocket(sock);
                                  return -2;
                                  }

                                  ...


                                  Note, however, that the above returns only the first address found. A hostname can resolve to multiple IPs, and your PC might not have a route to all of them. So, you should attempt to connect to every address reported until one is successful, eg:



                                  int lookup_host(const wchar_t *host, int family, struct addrinfoW **addrs)
                                  {
                                  struct addrinfoW hints;
                                  int errcode;

                                  ZeroMemory(&hints, sizeof(hints));
                                  hints.ai_family = family;
                                  hints.ai_socktype = SOCK_STREAM;

                                  errcode = GetAddrInfoW(host, L"80", &hints, addrs);
                                  //GetAddrInfoExW(host, L"80", NS_ALL, NULL, &hints, addrs, NULL, NULL, NULL, NULL);
                                  if (errcode != 0)
                                  {
                                  //perror("getaddrinfo");
                                  return -1;
                                  }

                                  return 0;
                                  }

                                  ...

                                  struct addrInfoW *res, *addr;

                                  if (lookup_host(host, AF_INET, &res) < 0) { // or AF_INET6, or AF_UNSPEC
                                  return -1;
                                  }

                                  sock = INVALID_SOCKET;

                                  for(addr = res; addr != NULL; addr = addr->ai_next)
                                  {
                                  sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
                                  if (sock == INVALID_SOCKET) {
                                  break;
                                  }

                                  if (connect(sock, addr->ai_addr, addr->ai_addrlen) == 0) {
                                  break;
                                  }

                                  #ifdef _DEBUG
                                  printf("Error: %dn", GetLastError());
                                  #endif // _DEBUG

                                  closesocket(sock);
                                  sock = INVALID_SOCKET;
                                  }

                                  FreeAddrInfoW(res);

                                  if (sock == INVALID_SOCKET) {
                                  return -2;
                                  }

                                  ...





                                  share|improve this answer




























                                    0












                                    0








                                    0







                                    Your lookup_host() is not returning address data back to the caller correctly, not even close. addrinfo contains pointers to data outside of the addrinfo. But you are just copying the addrinfo itself to the caller, but none of the data it points at.



                                    Try something more like this instead:



                                    int lookup_host(const wchar_t *host, int family, void *sa)
                                    {
                                    struct addrinfoW hints;
                                    struct addrinfoW *res, *addr;
                                    int errcode, addrlen, returnval;
                                    void *ptr;

                                    ZeroMemory(&hints, sizeof(hints));
                                    hints.ai_family = family;
                                    hints.ai_socktype = SOCK_STREAM;

                                    errcode = GetAddrInfoW(host, L"80", &hints, &res);
                                    //GetAddrInfoExW(host, L"80", NS_ALL, NULL, &hints, &res, NULL, NULL, NULL, NULL);
                                    if (errcode != 0)
                                    {
                                    //perror("getaddrinfo");
                                    return -1;
                                    }

                                    returnval = 0;

                                    for(addr = res; addr != NULL; addr = addr->ai_next)
                                    {
                                    switch (addr->ai_family)
                                    {
                                    case AF_INET:
                                    ptr = &((struct sockaddr_in *) addr->ai_addr)->sin_addr;
                                    addrlen = sizeof(struct sockaddr_in);
                                    break;

                                    case AF_INET6:
                                    ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
                                    addrlen = sizeof(struct sockaddr_in6);
                                    break;

                                    default:
                                    continue;
                                    }

                                    CopyMemory(sa, ptr, addrlen);
                                    returnval = 1;
                                    break;
                                    }

                                    FreeAddrInfoW(res);

                                    return returnval;
                                    }

                                    ...

                                    struct sockaddr_in sa;

                                    if (lookup_host(host, AF_INET, &sa) != 1) {
                                    return -1;
                                    }

                                    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
                                    if (sock == INVALID_SOCKET) {
                                    return -1;
                                    }

                                    if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
                                    #ifdef _DEBUG
                                    printf("Error: %dn", GetLastError());
                                    #endif // _DEBUG

                                    closesocket(sock);
                                    return -2;
                                    }

                                    ...


                                    Note, however, that the above returns only the first address found. A hostname can resolve to multiple IPs, and your PC might not have a route to all of them. So, you should attempt to connect to every address reported until one is successful, eg:



                                    int lookup_host(const wchar_t *host, int family, struct addrinfoW **addrs)
                                    {
                                    struct addrinfoW hints;
                                    int errcode;

                                    ZeroMemory(&hints, sizeof(hints));
                                    hints.ai_family = family;
                                    hints.ai_socktype = SOCK_STREAM;

                                    errcode = GetAddrInfoW(host, L"80", &hints, addrs);
                                    //GetAddrInfoExW(host, L"80", NS_ALL, NULL, &hints, addrs, NULL, NULL, NULL, NULL);
                                    if (errcode != 0)
                                    {
                                    //perror("getaddrinfo");
                                    return -1;
                                    }

                                    return 0;
                                    }

                                    ...

                                    struct addrInfoW *res, *addr;

                                    if (lookup_host(host, AF_INET, &res) < 0) { // or AF_INET6, or AF_UNSPEC
                                    return -1;
                                    }

                                    sock = INVALID_SOCKET;

                                    for(addr = res; addr != NULL; addr = addr->ai_next)
                                    {
                                    sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
                                    if (sock == INVALID_SOCKET) {
                                    break;
                                    }

                                    if (connect(sock, addr->ai_addr, addr->ai_addrlen) == 0) {
                                    break;
                                    }

                                    #ifdef _DEBUG
                                    printf("Error: %dn", GetLastError());
                                    #endif // _DEBUG

                                    closesocket(sock);
                                    sock = INVALID_SOCKET;
                                    }

                                    FreeAddrInfoW(res);

                                    if (sock == INVALID_SOCKET) {
                                    return -2;
                                    }

                                    ...





                                    share|improve this answer















                                    Your lookup_host() is not returning address data back to the caller correctly, not even close. addrinfo contains pointers to data outside of the addrinfo. But you are just copying the addrinfo itself to the caller, but none of the data it points at.



                                    Try something more like this instead:



                                    int lookup_host(const wchar_t *host, int family, void *sa)
                                    {
                                    struct addrinfoW hints;
                                    struct addrinfoW *res, *addr;
                                    int errcode, addrlen, returnval;
                                    void *ptr;

                                    ZeroMemory(&hints, sizeof(hints));
                                    hints.ai_family = family;
                                    hints.ai_socktype = SOCK_STREAM;

                                    errcode = GetAddrInfoW(host, L"80", &hints, &res);
                                    //GetAddrInfoExW(host, L"80", NS_ALL, NULL, &hints, &res, NULL, NULL, NULL, NULL);
                                    if (errcode != 0)
                                    {
                                    //perror("getaddrinfo");
                                    return -1;
                                    }

                                    returnval = 0;

                                    for(addr = res; addr != NULL; addr = addr->ai_next)
                                    {
                                    switch (addr->ai_family)
                                    {
                                    case AF_INET:
                                    ptr = &((struct sockaddr_in *) addr->ai_addr)->sin_addr;
                                    addrlen = sizeof(struct sockaddr_in);
                                    break;

                                    case AF_INET6:
                                    ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
                                    addrlen = sizeof(struct sockaddr_in6);
                                    break;

                                    default:
                                    continue;
                                    }

                                    CopyMemory(sa, ptr, addrlen);
                                    returnval = 1;
                                    break;
                                    }

                                    FreeAddrInfoW(res);

                                    return returnval;
                                    }

                                    ...

                                    struct sockaddr_in sa;

                                    if (lookup_host(host, AF_INET, &sa) != 1) {
                                    return -1;
                                    }

                                    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
                                    if (sock == INVALID_SOCKET) {
                                    return -1;
                                    }

                                    if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
                                    #ifdef _DEBUG
                                    printf("Error: %dn", GetLastError());
                                    #endif // _DEBUG

                                    closesocket(sock);
                                    return -2;
                                    }

                                    ...


                                    Note, however, that the above returns only the first address found. A hostname can resolve to multiple IPs, and your PC might not have a route to all of them. So, you should attempt to connect to every address reported until one is successful, eg:



                                    int lookup_host(const wchar_t *host, int family, struct addrinfoW **addrs)
                                    {
                                    struct addrinfoW hints;
                                    int errcode;

                                    ZeroMemory(&hints, sizeof(hints));
                                    hints.ai_family = family;
                                    hints.ai_socktype = SOCK_STREAM;

                                    errcode = GetAddrInfoW(host, L"80", &hints, addrs);
                                    //GetAddrInfoExW(host, L"80", NS_ALL, NULL, &hints, addrs, NULL, NULL, NULL, NULL);
                                    if (errcode != 0)
                                    {
                                    //perror("getaddrinfo");
                                    return -1;
                                    }

                                    return 0;
                                    }

                                    ...

                                    struct addrInfoW *res, *addr;

                                    if (lookup_host(host, AF_INET, &res) < 0) { // or AF_INET6, or AF_UNSPEC
                                    return -1;
                                    }

                                    sock = INVALID_SOCKET;

                                    for(addr = res; addr != NULL; addr = addr->ai_next)
                                    {
                                    sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
                                    if (sock == INVALID_SOCKET) {
                                    break;
                                    }

                                    if (connect(sock, addr->ai_addr, addr->ai_addrlen) == 0) {
                                    break;
                                    }

                                    #ifdef _DEBUG
                                    printf("Error: %dn", GetLastError());
                                    #endif // _DEBUG

                                    closesocket(sock);
                                    sock = INVALID_SOCKET;
                                    }

                                    FreeAddrInfoW(res);

                                    if (sock == INVALID_SOCKET) {
                                    return -2;
                                    }

                                    ...






                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Nov 14 '18 at 21:52

























                                    answered Nov 14 '18 at 21:40









                                    Remy LebeauRemy Lebeau

                                    336k18256451




                                    336k18256451






























                                        draft saved

                                        draft discarded




















































                                        Thanks for contributing an answer to Stack Overflow!


                                        • Please be sure to answer the question. Provide details and share your research!

                                        But avoid



                                        • Asking for help, clarification, or responding to other answers.

                                        • Making statements based on opinion; back them up with references or personal experience.


                                        To learn more, see our tips on writing great answers.




                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function () {
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53300622%2fc-addrinfo-struct-gets-corrupted-but-heap-is-still-valid%23new-answer', 'question_page');
                                        }
                                        );

                                        Post as a guest















                                        Required, but never shown





















































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown

































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown







                                        Popular posts from this blog

                                        Xamarin.iOS Cant Deploy on Iphone

                                        Glorious Revolution

                                        Dulmage-Mendelsohn matrix decomposition in Python