[eggheads-patches] PATCH1.5: save_data_1.5.patch

Fabian Knittel fknittel at gmx.de
Mon Oct 23 16:31:06 CST 2000


[ save_data_1.5.patch ]

This patch avoids data lossage during the start of connections, i.e.
when eggdrop's dcc handlers try to look up the hostname, gather
ident information and pass the socket around a bit.

Normally, all data would be simply dropped, but with this patch it
is stored in the already existing socket buffers and flushed as soon
as the connections gets a proper dcc handler.

Fabian

--
Fabian Knittel <fknittel at gmx.de> -- http://www.esc-web.de/fabian/
Signed or encrypted mail preferred.    PGP DSA key ID: 0x838B4D20
-------------- next part --------------
diff -urN --exclude-from=/home/fabian/.diffex eggdrop1.5~/doc/UPDATES1.5 eggdrop1.5/doc/UPDATES1.5
--- eggdrop1.5~/doc/UPDATES1.5	Mon Oct 23 23:28:52 2000
+++ eggdrop1.5/doc/UPDATES1.5	Mon Oct 23 23:37:45 2000
@@ -4,6 +4,10 @@
 
 1.5.5
 Found by  Fixed by  What...
+          Fabian    Avoid data lossage during the start of connections, while
+                    the receiving dcc functions aren't listening yet. So now
+                    you can blindly start sending data right after connecting
+                    and depend on the OS and eggdrop to do The Right Thing.
 Abraham,  Fabian    Changed failure of socket() to non-fatal event.
 TaKeDa
 TheUnknown Fabian   Fixed support for SunOS / Solaris.
diff -urN --exclude-from=/home/fabian/.diffex eggdrop1.5~/src/dcc.c eggdrop1.5/src/dcc.c
--- eggdrop1.5~/src/dcc.c	Mon Oct 23 23:28:52 2000
+++ eggdrop1.5/src/dcc.c	Mon Oct 23 23:32:43 2000
@@ -1124,6 +1124,9 @@
     putlog(LOG_MISC, "*", DCC_FAILED, s);
     return;
   }
+  /* Buffer data received on this socket.  */
+  sockoptions(sock, EGG_OPTION_SET, SOCK_BUFFER);
+
   /* <bindle> [09:37] Telnet connection: 168.246.255.191/0
    * <bindle> [09:37] Lost connection while identing [168.246.255.191/0]
    */
@@ -2091,6 +2094,10 @@
     check_tcl_listen(dcc[idx].host, dcc[i].sock);
     return;
   }
+  /* Do not buffer data anymore. All received and stored data is passed
+     over to the dcc functions from now on.  */
+  sockoptions(dcc[i].sock, EGG_OPTION_UNSET, SOCK_BUFFER);
+
   dcc[i].type = &DCC_TELNET_ID;
   dcc[i].u.chat = get_data_ptr(sizeof(struct chat_info));
   egg_bzero(dcc[i].u.chat, sizeof(struct chat_info));
diff -urN --exclude-from=/home/fabian/.diffex eggdrop1.5~/src/eggdrop.h eggdrop1.5/src/eggdrop.h
--- eggdrop1.5~/src/eggdrop.h	Mon Oct 23 22:42:37 2000
+++ eggdrop1.5/src/eggdrop.h	Mon Oct 23 23:32:43 2000
@@ -519,6 +519,7 @@
 #define SOCK_PASS	0x0100	/* passed on; only notify in case
 				   of traffic				*/
 #define SOCK_VIRTUAL	0x0200	/* not-connected socket (dont read it!)	*/
+#define SOCK_BUFFER	0x0400	/* buffer data; don't notify dcc funcs	*/
 
 /* Flags to sock_has_data
  */
@@ -567,9 +568,14 @@
   short		 flags;
   char		*inbuf;
   char		*outbuf;
-  unsigned long  outbuflen;	/* Outbuf could be binary data */
+  unsigned long  outbuflen;	/* Outbuf could be binary data	*/
+  unsigned long	 inbuflen;	/* Inbuf could be binary data	*/
 } sock_list;
 
+enum {
+  EGG_OPTION_SET	= 1,	/* Set option(s).		*/
+  EGG_OPTION_UNSET	= 2	/* Unset option(s).		*/
+};
 
 /* Telnet codes.  See "TELNET Protocol Specification" (RFC 854) and
  * "TELNET Echo Option" (RFC 875) for details.
diff -urN --exclude-from=/home/fabian/.diffex eggdrop1.5~/src/net.c eggdrop1.5/src/net.c
--- eggdrop1.5~/src/net.c	Mon Oct 23 23:28:52 2000
+++ eggdrop1.5/src/net.c	Mon Oct 23 23:32:43 2000
@@ -199,6 +199,30 @@
   }
 }
 
+/* Sets/Unsets options for a specific socket.
+ * 
+ * Returns:  0   - on success
+ *           -1  - socket not found
+ *           -2  - illegal operation
+ */
+int sockoptions(int sock, int operation, int sock_options)
+{
+  int i;
+
+  Context;
+  for (i = 0; i < MAXSOCKS; i++)
+    if (socklist[i].sock == sock) {
+      if (operation == EGG_OPTION_SET)
+	      socklist[i].flags |= sock_options;
+      else if (operation == EGG_OPTION_UNSET)
+	      socklist[i].flags &= ~sock_options;
+      else
+	      return -2;
+      return 0;
+    }
+  return -1;
+}
+
 /* Return a free entry in the socket entry
  */
 int allocsock(int sock, int options)
@@ -209,7 +233,7 @@
     if (socklist[i].flags & SOCK_UNUSED) {
       /* yay!  there is table space */
       socklist[i].inbuf = socklist[i].outbuf = NULL;
-      socklist[i].outbuflen = 0;
+      socklist[i].inbuflen = socklist[i].outbuflen = 0;
       socklist[i].flags = options;
       socklist[i].sock = sock;
       return i;
@@ -519,8 +543,8 @@
   int new_sock;
   unsigned int addrlen;
   struct sockaddr_in from;
-  addrlen = sizeof(struct sockaddr);
 
+  addrlen = sizeof(struct sockaddr);
   new_sock = accept(sock, (struct sockaddr *) &from, &addrlen);
   if (new_sock < 0)
     return -1;
@@ -703,6 +727,9 @@
  * if an EOF is detected from any of the sockets, that socket number will be
  * put in len, and -1 will be returned.
  * the maximum length of the string returned is 512 (including null)
+ *
+ * Returns -4 if we handled something that shouldn't be handled by the
+ * dcc functions. Simply ignore it.
  */
 
 int sockgets(char *s, int *len)
@@ -713,29 +740,49 @@
   Context;
   for (i = 0; i < MAXSOCKS; i++) {
     /* Check for stored-up data waiting to be processed */
-    if (!(socklist[i].flags & SOCK_UNUSED) && (socklist[i].inbuf != NULL)) {
-      /* look for \r too cos windows can't follow RFCs */
-      p = strchr(socklist[i].inbuf, '\n');
-      if (p == NULL)
-	p = strchr(socklist[i].inbuf, '\r');
-      if (p != NULL) {
-	*p = 0;
-	if (strlen(socklist[i].inbuf) > 510)
-	  socklist[i].inbuf[510] = 0;
-	strcpy(s, socklist[i].inbuf);
-	px = (char *) nmalloc(strlen(p + 1) + 1);
-	strcpy(px, p + 1);
-	nfree(socklist[i].inbuf);
-	if (px[0])
-	  socklist[i].inbuf = px;
-	else {
-	  nfree(px);
-	  socklist[i].inbuf = NULL;
+    if (!(socklist[i].flags & SOCK_UNUSED) &&
+	!(socklist[i].flags & SOCK_BUFFER) && (socklist[i].inbuf != NULL)) {
+      if (!(socklist[i].flags & SOCK_BINARY)) {
+	/* look for \r too cos windows can't follow RFCs */
+	p = strchr(socklist[i].inbuf, '\n');
+	if (p == NULL)
+	  p = strchr(socklist[i].inbuf, '\r');
+	if (p != NULL) {
+	  *p = 0;
+	  if (strlen(socklist[i].inbuf) > 510)
+	    socklist[i].inbuf[510] = 0;
+	  strcpy(s, socklist[i].inbuf);
+	  px = (char *) nmalloc(strlen(p + 1) + 1);
+	  strcpy(px, p + 1);
+	  nfree(socklist[i].inbuf);
+	  if (px[0])
+	    socklist[i].inbuf = px;
+	  else {
+	    nfree(px);
+	    socklist[i].inbuf = NULL;
+	  }
+	  /* Strip CR if this was CR/LF combo */
+	  if (s[strlen(s) - 1] == '\r')
+	    s[strlen(s) - 1] = 0;
+	  *len = strlen(s);
+	  return socklist[i].sock;
+	}
+      } else {
+	/* Handling buffered binary data (must have been SOCK_BUFFER before). */
+	if (socklist[i].inbuflen <= 510) {
+	  *len = socklist[i].inbuflen;
+	  egg_memcpy(s, socklist[i].inbuf, socklist[i].inbuflen);
+	  nfree(socklist[i].inbuf);
+	  socklist[i].inbuflen = 0;
+	} else {
+	  /* Split up into chunks of 510 bytes. */
+	  *len = 510;
+	  egg_memcpy(s, socklist[i].inbuf, *len);
+	  egg_memcpy(socklist[i].inbuf, socklist[i].inbuf + *len, *len);
+	  socklist[i].inbuflen -= *len;
+	  socklist[i].inbuf = nrealloc(socklist[i].inbuf,
+				       socklist[i].inbuflen);
 	}
-	/* Strip CR if this was CR/LF combo */
-	if (s[strlen(s) - 1] == '\r')
-	  s[strlen(s) - 1] = 0;
-	*len = strlen(s);
 	return socklist[i].sock;
       }
     }
@@ -760,9 +807,12 @@
   if (socklist[ret].flags & SOCK_CONNECT) {
     if (socklist[ret].flags & SOCK_STRONGCONN) {
       socklist[ret].flags &= ~SOCK_STRONGCONN;
-      /* Buffer any data that came in, for future read */
-      socklist[ret].inbuf = (char *) nmalloc(strlen(xx) + 1);
-      strcpy(socklist[ret].inbuf, xx);
+      /* Buffer any data that came in, for future read. */
+      socklist[ret].inbuflen = *len;
+      socklist[ret].inbuf = (char *) nmalloc(*len + 1);
+      /* It might be binary data. You never know. */
+      egg_memcpy(socklist[ret].inbuf, xx, *len);
+      socklist[ret].inbuf[*len] = 0;
     }
     socklist[ret].flags &= ~SOCK_CONNECT;
     s[0] = 0;
@@ -775,6 +825,16 @@
   if ((socklist[ret].flags & SOCK_LISTEN) ||
       (socklist[ret].flags & SOCK_PASS))
     return socklist[ret].sock;
+  if (socklist[ret].flags & SOCK_BUFFER) {
+    socklist[ret].inbuf = (char *) nrealloc(socklist[ret].inbuf,
+		    			    socklist[ret].inbuflen + *len + 1);
+    egg_memcpy(socklist[ret].inbuf + socklist[ret].inbuflen, xx, *len);
+    socklist[ret].inbuflen += *len;
+    /* We don't know whether it's binary data. Make sure normal strings
+       will be handled properly later on too. */
+    socklist[ret].inbuf[socklist[ret].inbuflen] = 0;
+    return -4;	/* Ignore this one. */
+  }
   Context;
   /* Might be necessary to prepend stored-up data! */
   if (socklist[ret].inbuf != NULL) {
@@ -787,9 +847,11 @@
       strcpy(xx, socklist[ret].inbuf);
       nfree(socklist[ret].inbuf);
       socklist[ret].inbuf = NULL;
+      socklist[ret].inbuflen = 0;
     } else {
       p = socklist[ret].inbuf;
-      socklist[ret].inbuf = (char *) nmalloc(strlen(p) - 509);
+      socklist[ret].inbuflen = strlen(p) - 510;
+      socklist[ret].inbuf = (char *) nmalloc(socklist[ret].inbuflen + 1);
       strcpy(socklist[ret].inbuf, p + 510);
       *(p + 510) = 0;
       strcpy(xx, p);
@@ -835,13 +897,15 @@
   if (socklist[ret].inbuf != NULL) {
     Context;
     p = socklist[ret].inbuf;
-    socklist[ret].inbuf = (char *) nmalloc(strlen(p) + strlen(xx) + 1);
+    socklist[ret].inbuflen = strlen(p) + strlen(xx);
+    socklist[ret].inbuf = (char *) nmalloc(socklist[ret].inbuflen + 1);
     strcpy(socklist[ret].inbuf, xx);
     strcat(socklist[ret].inbuf, p);
     nfree(p);
   } else {
     Context;
-    socklist[ret].inbuf = (char *) nmalloc(strlen(xx) + 1);
+    socklist[ret].inbuflen = strlen(xx);
+    socklist[ret].inbuf = (char *) nmalloc(socklist[ret].inbuflen + 1);
     strcpy(socklist[ret].inbuf, xx);
   }
   Context;
diff -urN --exclude-from=/home/fabian/.diffex eggdrop1.5~/src/proto.h eggdrop1.5/src/proto.h
--- eggdrop1.5~/src/proto.h	Mon Oct 23 23:19:30 2000
+++ eggdrop1.5/src/proto.h	Mon Oct 23 23:32:43 2000
@@ -257,6 +257,7 @@
 int hostsanitycheck_dcc(char *, char *, IP, char *, char *);
 char *iptostr(IP);
 int sock_has_data(int, int);
+int sockoptions(int sock, int operation, int sock_options);
 
 /* tcl.c */
 void protect_tcl();
diff -urN --exclude-from=/home/fabian/.diffex eggdrop1.5~/src/tcldcc.c eggdrop1.5/src/tcldcc.c
--- eggdrop1.5~/src/tcldcc.c	Mon Oct 23 23:28:52 2000
+++ eggdrop1.5/src/tcldcc.c	Mon Oct 23 23:32:43 2000
@@ -486,6 +486,9 @@
   dcc[idx].u.script->u.other = hold;
   dcc[idx].u.script->type = dcc[idx].type;
   dcc[idx].type = &DCC_SCRIPT;
+  /* Do not buffer data anymore. All received and stored data is passed
+     over to the dcc functions from now on.  */
+  sockoptions(dcc[idx].sock, EGG_OPTION_UNSET, SOCK_BUFFER);
   strncpy(dcc[idx].u.script->command, argv[2], 120);
   dcc[idx].u.script->command[120] = 0;
   return TCL_OK;




More information about the Patches mailing list