]> jfr.im git - irc/rizon/plexus4.git/commitdiff
Read packets until there is no more, with ssl it is possible data can be buffered...
authorAdam <redacted>
Thu, 23 Jun 2016 18:54:05 +0000 (14:54 -0400)
committerAdam <redacted>
Thu, 23 Jun 2016 18:54:05 +0000 (14:54 -0400)
src/packet.c

index 836b2fe7919ef8fd1d2ce4678f770dac27565a96..9d8808daff6cb629d8745063bc95902dfe4743c8 100644 (file)
@@ -284,82 +284,86 @@ read_packet(fde_t *fd, void *data)
   if (IsDefunct(client_p))
     return;
 
-  /*
-   * Read some data. We *used to* do anti-flood protection here, but
-   * I personally think it makes the code too hairy to make sane.
-   *     -- adrian
-   */
-  if (fd->ssl)
+  do
   {
-    ERR_clear_error();
-    length = SSL_read(fd->ssl, readBuf, READBUF_SIZE);
+    /*
+     * Read some data. We *used to* do anti-flood protection here, but
+     * I personally think it makes the code too hairy to make sane.
+     *     -- adrian
+     */
+    if (fd->ssl)
+    {
+      ERR_clear_error();
+      length = SSL_read(fd->ssl, readBuf, READBUF_SIZE);
+
+      if (!IsServer(client_p) && fd->renegotiations > 1)
+      {
+        exit_client(client_p, &me, "SSL renegotiation not allowed");
+        return;
+      }
 
-    if (!IsServer(client_p) && fd->renegotiations > 1)
+      /* translate openssl error codes, sigh */
+      if (length < 0)
+        switch (SSL_get_error(fd->ssl, length))
+        {
+          case SSL_ERROR_WANT_WRITE:
+            comm_setselect(fd, COMM_SELECT_WRITE, (PF *) sendq_unblocked, client_p);
+            return;
+          case SSL_ERROR_WANT_READ:
+              errno = EWOULDBLOCK;
+          case SSL_ERROR_SYSCALL:
+              break;
+          case SSL_ERROR_SSL:
+            if (errno == EAGAIN)
+              break;
+          default:
+            length = errno = 0;
+        }
+    }
+    else
     {
-      exit_client(client_p, &me, "SSL renegotiation not allowed");
-      return;
+      length = recv(fd->fd, readBuf, READBUF_SIZE, 0);
     }
 
-    /* translate openssl error codes, sigh */
-    if (length < 0)
-      switch (SSL_get_error(fd->ssl, length))
+    if (length <= 0)
+    {
+      if (length < 0 && ignoreErrno(errno))
       {
-        case SSL_ERROR_WANT_WRITE:
-          comm_setselect(fd, COMM_SELECT_WRITE, (PF *) sendq_unblocked, client_p);
-          return;
-        case SSL_ERROR_WANT_READ:
-            errno = EWOULDBLOCK;
-        case SSL_ERROR_SYSCALL:
-            break;
-        case SSL_ERROR_SSL:
-          if (errno == EAGAIN)
-            break;
-        default:
-          length = errno = 0;
+        comm_setselect(fd, COMM_SELECT_READ, read_packet, client_p);
+        return;
       }
-  }
-  else
-  {
-    length = recv(fd->fd, readBuf, READBUF_SIZE, 0);
-  }
 
-  if (length <= 0)
-  {
-    if (length < 0 && ignoreErrno(errno))
-    {
-      comm_setselect(fd, COMM_SELECT_READ, read_packet, client_p);
+      dead_link_on_read(client_p, length);
       return;
     }
 
-    dead_link_on_read(client_p, length);
-    return;
-  }
+    dbuf_put(&client_p->localClient->buf_recvq, readBuf, length);
 
-  dbuf_put(&client_p->localClient->buf_recvq, readBuf, length);
+    if (client_p->localClient->lasttime < CurrentTime)
+      client_p->localClient->lasttime = CurrentTime;
+    if (client_p->localClient->lasttime > client_p->localClient->since)
+      client_p->localClient->since = CurrentTime;
+    ClearPingSent(client_p);
 
-  if (client_p->localClient->lasttime < CurrentTime)
-    client_p->localClient->lasttime = CurrentTime;
-  if (client_p->localClient->lasttime > client_p->localClient->since)
-    client_p->localClient->since = CurrentTime;
-  ClearPingSent(client_p);
-
-  /* Attempt to parse what we have */
-  parse_client_queued(client_p);
+    /* Attempt to parse what we have */
+    parse_client_queued(client_p);
 
-  if (IsDefunct(client_p))
-    return;
+    if (IsDefunct(client_p))
+      return;
 
-  if (IsServer(client_p) && HasSFlag(client_p, SERVER_FLAGS_MIGRATING_BLOCK_READ))
-    return;
+    if (IsServer(client_p) && HasSFlag(client_p, SERVER_FLAGS_MIGRATING_BLOCK_READ))
+      return;
 
-  /* Check to make sure we're not flooding */
-  if (!(IsServer(client_p) || IsHandshake(client_p) || IsConnecting(client_p))
-      && (dbuf_length(&client_p->localClient->buf_recvq) >
-          get_recvq(&client_p->localClient->confs)))
-  {
-    exit_client(client_p, client_p, "Excess Flood");
-    return;
+    /* Check to make sure we're not flooding */
+    if (!(IsServer(client_p) || IsHandshake(client_p) || IsConnecting(client_p))
+        && (dbuf_length(&client_p->localClient->buf_recvq) >
+            get_recvq(&client_p->localClient->confs)))
+    {
+      exit_client(client_p, client_p, "Excess Flood");
+      return;
+    }
   }
+  while (length == sizeof(readBuf) || fd->ssl != NULL);
 
   /* If we get here, we need to register for another COMM_SELECT_READ */
   comm_setselect(fd, COMM_SELECT_READ, read_packet, client_p);