net: Split socket create/connect #11363

pull theuni wants to merge 4 commits into bitcoin:master from theuni:split-socket-create-connect changing 3 files +63 −82
  1. theuni commented at 2:24 AM on September 19, 2017: member

    Requirement for #11227.

    We'll need to create sockets and perform the actual connect in separate steps, so break them up.

    #11227 adds an RAII wrapper around connection attempts, as a belt-and-suspenders in case a CloseSocket is missed.

  2. theuni renamed this:
    net: Split socket create connect
    net: Split socket create/connect
    on Sep 19, 2017
  3. jonasschnelli added the label P2P on Sep 19, 2017
  4. in src/netbase.cpp:611 in 3d91bc7aa4 outdated
     566 | @@ -554,8 +567,6 @@ bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int
     567 |          if (!Socks5(strDest, (unsigned short)port, 0, hSocket))
     568 |              return false;
     569 |      }
     570 | -
     571 | -    hSocketRet = hSocket;
    


    promag commented at 12:19 AM on September 20, 2017:

    If socks negotiation fail then hSocket will not be INVALID_SOCKET which is a different behavior than before. This also indicates that there is a leak in master because hSocket is not freed?


    theuni commented at 1:51 AM on September 20, 2017:

    Nice Catch! Force-pushed the missing CloseSocket()s.

    diff --git a/src/netbase.cpp b/src/netbase.cpp
    index 18763d2..4b72826 100644
    --- a/src/netbase.cpp
    +++ b/src/netbase.cpp
    @@ -561,11 +561,15 @@ bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int
             ProxyCredentials random_auth;
             static std::atomic_int counter(0);
             random_auth.username = random_auth.password = strprintf("%i", counter++);
    -        if (!Socks5(strDest, (unsigned short)port, &random_auth, hSocket))
    +        if (!Socks5(strDest, (unsigned short)port, &random_auth, hSocket)) {
    +            CloseSocket(hSocket);
                 return false;
    +        }
         } else {
    -        if (!Socks5(strDest, (unsigned short)port, 0, hSocket))
    +        if (!Socks5(strDest, (unsigned short)port, 0, hSocket)) {
    +            CloseSocket(hSocket);
                 return false;
    +        }
         }
         return true;
     }
    

    promag commented at 10:09 AM on September 20, 2017:

    CloseSocket sets hSocket to INVALID_SOCKET so this LGTM. I wonder if you could just return CloseSocket(hSocket)?


    theuni commented at 5:15 PM on September 20, 2017:

    CloseSocket's return value indicates whether the close succeeded or not, which would be true in this case. Not what we want :)


    promag commented at 9:44 AM on September 21, 2017:

    Ahhh yeah... now I win the most stupid comment award.


    theuni commented at 2:48 PM on September 21, 2017:

    Hah, no worries. We'll call it even for pointing out my mistake here

  5. promag commented at 12:24 AM on September 20, 2017: member

    I'm not yet familiar with P2P code to ACK. In any case see my comment below.

  6. theuni force-pushed on Sep 20, 2017
  7. theuni force-pushed on Sep 20, 2017
  8. theuni force-pushed on Sep 28, 2017
  9. theuni commented at 6:12 PM on September 28, 2017: member

    Rebased after #10663.

    Also, changed from the last version: Rather than passing in a socket reference and returning a bool, CreateSocket() now returns a socket (which may be invalid) instead. That's much more straightforward, IMO, and matches the usage of socket().

  10. in src/netbase.cpp:439 in 29e0a1605d outdated
     451 | @@ -452,10 +452,8 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
     452 |      return true;
     453 |  }
     454 |  
     455 | -bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout)
     456 | +SOCKET CreateSocket(const CService &addrConnect)
    


    TheBlueMatt commented at 11:48 PM on September 28, 2017:

    You need to change the return values values of all the "return false"s in here - INVALID_SOCKET is (currently) ~0, so we will pretend the socket creation succeeded.


    theuni commented at 12:07 AM on September 29, 2017:

    Thanks, don't know how I missed those.

  11. in src/netbase.cpp:495 in 29e0a1605d outdated
     491 | +        LogPrintf("Cannot connect to %s: invalid socket\n", addrConnect.ToString());
     492 | +        return false;
     493 | +    }
     494 | +    if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
     495 | +        LogPrintf("Cannot connect to %s: unsupported network\n", addrConnect.ToString());
     496 | +        CloseSocket(hSocket);
    


    TheBlueMatt commented at 11:50 PM on September 28, 2017:

    At the risk of making you redo a bunch of work, is it possible to const-ify the socket here and make the caller do the CloseSocket instead? Shits currently a maze and it'd be nice to clean it up sooner rather than try to follow it through the libevent changes.


    theuni commented at 12:17 AM on September 29, 2017:

    Yes, that makes sense. Now that we don't have chained connect functions, it's much more clear what "the caller" means. The maze was only there because we had to close at all levels to be safe.

    Will do.

  12. theuni force-pushed on Oct 2, 2017
  13. fanquake added this to the "In progress" column in a project

  14. theuni force-pushed on Nov 7, 2017
  15. theuni force-pushed on Nov 7, 2017
  16. theuni commented at 9:22 PM on November 7, 2017: member

    Rebased and fixed the check against the connect() return value, which was already wrong, but doesn't really matter because it's always detected on first use anyway.

  17. TheBlueMatt commented at 9:23 PM on November 7, 2017: member

    utACK f766175ebe4400561f60b75b0ede4015003bad8c

  18. laanwj added this to the "Blockers" column in a project

  19. laanwj commented at 10:46 AM on December 12, 2017: member

    This gives me a new warning:

    /.../bitcoin/src/netbase.cpp:449:17: warning: comparison of integers of different signs: 'SOCKET' (aka 'unsigned int') and 'int' [-Wsign-compare]
        if (hSocket == -1)
            ~~~~~~~ ^  ~~
    1 warning generated.
    
  20. in src/net.cpp:2090 in f766175ebe outdated
    2095 | -
    2096 | -
    2097 |  #ifndef WIN32
    2098 | -#ifdef SO_NOSIGPIPE
    2099 | -    // Different way of disabling SIGPIPE on BSD
    2100 | -    setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
    


    laanwj commented at 11:37 AM on December 12, 2017:

    NOSIGPIPE handling moved to CreateSocket(addrBind)?


    TheBlueMatt commented at 7:13 PM on December 12, 2017:

    Yes, I think part of the goal is to get random socket flag-fiddling things out of net and into netbase, its kinda split between both right now. @theuni ?


    theuni commented at 8:10 PM on December 12, 2017:

    Yep. If it's something we require for all sockets, imo it makes sense to do it in CreateSocket.

  21. in src/net.cpp:2099 in f766175ebe outdated
    2104 |      setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
    2105 | -    // Disable Nagle's algorithm
    2106 | -    setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&nOne, sizeof(int));
    2107 |  #else
    2108 |      setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nOne, sizeof(int));
    2109 | -    setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&nOne, sizeof(int));
    


    laanwj commented at 11:38 AM on December 12, 2017:

    Where did this move? The only remaining reference to TCP_NODELAY I see is in SetSocketNoDelay, which is called on accepted sockets only.


    TheBlueMatt commented at 7:12 PM on December 12, 2017:

    Its also called in netbase.cpp in CreateSocket, so should be set for outbound and inbound connection sockets, though not the listen socket, but that makes sense.


    theuni commented at 8:16 PM on December 12, 2017:

    It's set on the listen socket as well (which should pass it down to accepted sockets anyway), since BindListenPort now uses CreateSocket().

  22. net: split socket creation out of connection
    Also, check for the correct error during socket creation
    1729c29ded
  23. net: Move IsSelectableSocket check into socket creation
    We use select in ConnectSocketDirectly, so this check needs to happen before
    that.
    
    IsSelectableSocket will not be relevant after upcoming changes to remove select.
    9e3b2f576b
  24. net: pass socket closing responsibility up to caller for outgoing connections
    This allows const references to be passed around, making it clear where the
    socket may and may not be invalidated.
    df3bcf89e4
  25. net: use CreateSocket for binds 3830b6e065
  26. theuni force-pushed on Dec 12, 2017
  27. theuni commented at 8:34 PM on December 12, 2017: member

    @laanwj Yes, thanks. Due to our SOCKET wrappers, we need to compare against INVALID_SOCKET rather than SOCKET_ERROR. Pushed the squashed change as it was very simple (it's actually just reverting a change from this PR, it was already correct in master).

    Diff from before: git diff f766175ebe44..3830b6e06591

    
    diff --git a/src/netbase.cpp b/src/netbase.cpp
    index ba2c988..74ea6b1 100644
    --- a/src/netbase.cpp
    +++ b/src/netbase.cpp
    @@ -446,7 +446,7 @@ SOCKET CreateSocket(const CService &addrConnect)
         }
     
         SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
    -    if (hSocket == SOCKET_ERROR)
    +    if (hSocket == INVALID_SOCKET)
             return INVALID_SOCKET;
     
         if (!IsSelectableSocket(hSocket)) {
    
  28. laanwj commented at 4:42 AM on December 13, 2017: member

    utACK 3830b6e0659106458c941029f5b2e789e3cb38a3

  29. laanwj merged this on Dec 13, 2017
  30. laanwj closed this on Dec 13, 2017

  31. laanwj referenced this in commit ba2f19504c on Dec 13, 2017
  32. laanwj removed this from the "Blockers" column in a project

  33. fanquake moved this from the "In progress" to the "Done" column in a project

  34. PastaPastaPasta referenced this in commit 7f88a67d5b on Jan 25, 2020
  35. ckti referenced this in commit 95574a85a4 on Mar 28, 2021
  36. gades referenced this in commit 652769becd on Jun 25, 2021
  37. DrahtBot locked this on Sep 8, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-18 15:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me