]> Git Repo - VerusCoin.git/commitdiff
P2P: improve RX/TX flow control
authorJeff Garzik <[email protected]>
Thu, 15 Nov 2012 23:20:26 +0000 (18:20 -0500)
committerPieter Wuille <[email protected]>
Fri, 29 Mar 2013 22:56:25 +0000 (23:56 +0100)
1) "optimistic write": Push each message to kernel socket buffer immediately.

2) If there is write data at select time, that implies send() blocked
   during optimistic write.  Drain write queue, before receiving
   any more messages.

This avoids needlessly queueing received data, if the remote peer
is not themselves receiving data.

Result: write buffer (and thus memory usage) is kept small, DoS
potential is slightly lower, and TCP flow control signalling is
properly utilized.

The kernel will queue data into the socket buffer, then signal the
remote peer to stop sending data, until we resume reading again.

src/net.cpp
src/net.h

index 96719367ceec49cf54962b6631a1abdaf8702c97..eafb3356426f7ca7e98b515e64c5c68458089d1e 100644 (file)
@@ -855,14 +855,18 @@ void ThreadSocketHandler2(void* parg)
             {
                 if (pnode->hSocket == INVALID_SOCKET)
                     continue;
-                FD_SET(pnode->hSocket, &fdsetRecv);
-                FD_SET(pnode->hSocket, &fdsetError);
-                hSocketMax = max(hSocketMax, pnode->hSocket);
-                have_fds = true;
                 {
                     TRY_LOCK(pnode->cs_vSend, lockSend);
-                    if (lockSend && !pnode->vSend.empty())
-                        FD_SET(pnode->hSocket, &fdsetSend);
+                    if (lockSend) {
+                        // do not read, if draining write queue
+                        if (!pnode->vSend.empty())
+                            FD_SET(pnode->hSocket, &fdsetSend);
+                        else
+                            FD_SET(pnode->hSocket, &fdsetRecv);
+                        FD_SET(pnode->hSocket, &fdsetError);
+                        hSocketMax = max(hSocketMax, pnode->hSocket);
+                        have_fds = true;
+                    }
                 }
             }
         }
index 78f8e72fb03a56d9d749e31f46574a0786696f89..03d32526bc5d01c7b23cbbd290ad57ac50913335 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -42,6 +42,7 @@ unsigned short GetListenPort();
 bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string()));
 void StartNode(void* parg);
 bool StopNode();
+void SocketSendData(CNode *pnode);
 
 enum
 {
@@ -437,6 +438,10 @@ public:
             printf("(%d bytes)\n", nSize);
         }
 
+        // If write queue empty, attempt "optimistic write"
+        if (nHeaderStart == 0)
+            SocketSendData(this);
+
         nHeaderStart = -1;
         nMessageStart = -1;
         LEAVE_CRITICAL_SECTION(cs_vSend);
This page took 0.030315 seconds and 4 git commands to generate.