- Lets put messages from connecting links through the right handler.
authorAndrew Miller <a1kmm@amxl.com>
Fri, 5 Jul 2002 02:09:44 +0000 (02:09 +0000)
committerAndrew Miller <a1kmm@amxl.com>
Fri, 5 Jul 2002 02:09:44 +0000 (02:09 +0000)
This seems to link perfectly from all the tests I can put it through,
so hopefully it will fix all the problems.

git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@787 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

ChangeLog
include/packet.h
ircd/packet.c
ircd/s_bsd.c

index 3f156caafc3999e914de1e86f24618975a6886d4..4e1883669c2dbb6a3bb80c56604a57c8357b192f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2002-07-05 Andrew Miller <a1kmm@mware.virtualave.net>
+       * ircd/packet.c
+       * ircd/packet.h: (connect_dopacket): Made a dopacket function for
+       connecting links which sends the messages through the correct message
+       handler.
+       * ircd/s_bsd.c(read_packet): Put packets through the correct handler
+       for connecting links. Properly handle unknown links becoming
+       connecting or servers.
+
 2002-07-01 Andrew Miller <a1kmm@mware.virtualave.net>
        * include/ircd_alloc.h (MyFree): Accept NULL pointers to do nothing
        with, this is used quite a lot.
index 848e99b6fca3387dc380af60c2bf5a15baff634d..e0c2a4bdcd381a6edf7e766cb80eb66de27542fb 100644 (file)
@@ -17,6 +17,7 @@ struct Client;
  */
 
 extern int server_dopacket(struct Client* cptr, const char* buffer, int length);
+extern int connect_dopacket(struct Client* cptr, const char* buffer, int length);
 extern int client_dopacket(struct Client* cptr, unsigned int length);
 
 #endif /* INCLUDED_packet_h */
index 59f8cd2f9a25469a1d56f8f1919a008e3d2c1f02..bfeebfa284dc5417f3a5f5dbab428b47eea611b4 100644 (file)
@@ -112,6 +112,54 @@ int server_dopacket(struct Client* cptr, const char* buffer, int length)
   return 1;
 }
 
+int connect_dopacket(struct Client *cptr, const char *buffer, int length)
+{
+  const char* src;
+  char*       endp;
+  char*       client_buffer;
+  
+  assert(0 != cptr);
+
+  update_bytes_received(cptr, length);
+
+  client_buffer = cli_buffer(cptr);
+  endp = client_buffer + cli_count(cptr);
+  src = buffer;
+
+  while (length-- > 0)
+  {
+    *endp = *src++;
+    /*
+     * Yuck.  Stuck.  To make sure we stay backward compatible,
+     * we must assume that either CR or LF terminates the message
+     * and not CR-LF.  By allowing CR or LF (alone) into the body
+     * of messages, backward compatibility is lost and major
+     * problems will arise. - Avalon
+     */
+    if (IsEol(*endp))
+    {
+      /* Skip extra LF/CR's */
+      if (endp == client_buffer)
+        continue;
+      *endp = '\0';
+
+      update_messages_received(cptr);
+
+      if (parse_client(cptr, cli_buffer(cptr), endp) == CPTR_KILLED)
+        return CPTR_KILLED;
+      /* Socket is dead so exit */
+      if (IsDead(cptr))
+        return exit_client(cptr, cptr, &me, cli_info(cptr));
+      endp = client_buffer;
+    }
+    else if (endp < client_buffer + BUFSIZE)
+      /* There is always room for the null */
+      ++endp;                   
+  }
+  cli_count(cptr) = endp - cli_buffer(cptr);
+  return 1;  
+}
+
 /*
  * client_dopacket - handle client messages
  */
index e2b4bdfaed65ecfb4a2ba14dc23b7c0a107a4f88..d44695718b43f3a0f27edea78436c93439fcf62e 100644 (file)
@@ -724,21 +724,24 @@ static int read_packet(struct Client *cptr, int socket_ready)
    * For server connections, we process as many as we can without
    * worrying about the time of day or anything :)
    */
-  if (length > 0 &&
-      (IsServer(cptr) || IsHandshake(cptr) || IsConnecting(cptr))) {
+  if (length <= 0)
+    ;
+  else if (IsServer(cptr))
+  {
     return server_dopacket(cptr, readbuf, length);
   }
-  else {
+  else if (IsHandshake(cptr) || IsConnecting(cptr))
+    return connect_dopacket(cptr, readbuf, length);
+  else
+  {
     /*
      * Before we even think of parsing what we just read, stick
      * it on the end of the receive queue and do it when its
      * turn comes around.
      */
-    if (length > 0 && 0 == dbuf_put(&(cli_recvQ(cptr)), readbuf, length)) {
+    if (dbuf_put(&(cli_recvQ(cptr)), readbuf, length) == 0)
       return exit_client(cptr, cptr, &me, "dbuf_put fail");
-    }
-
-    if (DBufLength(&(cli_recvQ(cptr))) > feature_int(FEAT_CLIENT_FLOOD))
+    else if (DBufLength(&(cli_recvQ(cptr))) > feature_int(FEAT_CLIENT_FLOOD))
       return exit_client(cptr, cptr, &me, "Excess Flood");
 
     while (DBufLength(&(cli_recvQ(cptr))) && !NoNewLine(cptr) && 
@@ -748,9 +751,19 @@ static int read_packet(struct Client *cptr, int socket_ready)
        * If it has become registered as a Server
        * then skip the per-message parsing below.
        */
-      if (IsServer(cptr)) {
-        dolen = dbuf_get(&(cli_recvQ(cptr)), readbuf, sizeof(readbuf));
-        return (dolen) ? server_dopacket(cptr, readbuf, dolen) : 1;
+      if (IsHandshake(cptr) || IsServer(cptr))
+      {
+        int ret;
+        while (-1)
+        {
+          dolen = dbuf_get(&(cli_recvQ(cptr)), readbuf, sizeof(readbuf));
+          if (dolen <= 0)
+            return 1;
+          ret = IsServer(cptr) ? server_dopacket(cptr, readbuf, dolen) :
+                                 connect_dopacket(cptr, readbuf, dolen);
+          if (ret != 1)
+            return ret;
+        }
       }
       dolen = dbuf_getmsg(&(cli_recvQ(cptr)), cli_buffer(cptr), BUFSIZE);
       /*
@@ -761,19 +774,21 @@ static int read_packet(struct Client *cptr, int socket_ready)
        * deletes the rest of the buffer contents.
        * -avalon
        */
-      if (0 == dolen) {
+      if (dolen = 0)
+      {
         if (DBufLength(&(cli_recvQ(cptr))) < 510)
           cli_flags(cptr) |= FLAGS_NONL;
         else
           DBufClear(&(cli_recvQ(cptr)));
       }
-      else if (CPTR_KILLED == client_dopacket(cptr, dolen))
+      else if (client_dopacket(cptr, dolen) == CPTR_KILLED)
         return CPTR_KILLED;
     }
 
     /* If there's still data to process, wait 2 seconds first */
     if (DBufLength(&(cli_recvQ(cptr))) && !NoNewLine(cptr) &&
-       !t_onqueue(&(cli_proc(cptr)))) {
+       !t_onqueue(&(cli_proc(cptr))))
+    {
       Debug((DEBUG_LIST, "Adding client process timer for %C", cptr));
       cli_freeflag(cptr) |= FREEFLAG_TIMER;
       timer_add(&(cli_proc(cptr)), client_timer_callback, cli_connect(cptr),