Index: ChangeLog =================================================================== RCS file: /cvsroot/crossfire/client/ChangeLog,v retrieving revision 1.95 diff -c -5 -r1.95 ChangeLog *** ChangeLog 12 Apr 2006 11:18:00 -0000 1.95 --- ChangeLog 14 May 2006 13:04:43 -0000 *************** *** 1,9 **** --- 1,18 ---- "$Id: ChangeLog,v 1.95 2006/04/12 11:18:00 cavesomething Exp $" Top of CVS tree: ------------------------------------------------------------------------------ + Make socket handling more robust. + --- + common/client.c: In DoClient() properly close the socket if an invalid packet + was received. + common/newclient.h: Increase the receive buffer size to 65535 bytes. This + allows the client to receive any valid packet (even if no currently + existing server is supposed to send such big packets). + Andreas Kirschbaum 2006-05-14 + common/image.c: use the same image hashing algorithm that the server uses for archetypes, increase the table size to 8192 to reduce collisions Brendan Lally 2006-04-12 common/item.c: fix unitialized variable. Index: common/client.c =================================================================== RCS file: /cvsroot/crossfire/client/common/client.c,v retrieving revision 1.32 diff -c -5 -r1.32 client.c *** common/client.c 26 Feb 2006 10:28:48 -0000 1.32 --- common/client.c 14 May 2006 13:04:43 -0000 *************** *** 136,160 **** while (1) { i=SockList_ReadPacket(csocket->fd, &csocket->inbuf, MAXSOCKBUF-1); if (i==-1) { /* Need to add some better logic here */ ! /*ET: not an error. It's EOF! At least errno isn't valid. ! fprintf(stderr,"Got error on read (error %d)\n", errno); ! */ csocket->fd=-1; return; } if (i==0) return; /* Don't have a full packet */ csocket->inbuf.buf[csocket->inbuf.len]='\0'; data = (unsigned char *)strchr((char*)csocket->inbuf.buf +2, ' '); if (data) { *data='\0'; data++; } len = csocket->inbuf.len - (data - csocket->inbuf.buf); - /* Terminate the buffer */ LOG(0,"Common::DoClient","Command:%s (%d)",csocket->inbuf.buf+2, len); for(i=0;i < NCOMMANDS;i++) { if (strcmp((char*)csocket->inbuf.buf+2,commands[i].cmdname)==0) { script_watch((char*)csocket->inbuf.buf+2,data,len,commands[i].cmdformat); commands[i].cmdproc(data,len); --- 136,162 ---- while (1) { i=SockList_ReadPacket(csocket->fd, &csocket->inbuf, MAXSOCKBUF-1); if (i==-1) { /* Need to add some better logic here */ ! #ifdef WIN32 ! closesocket(csocket->fd); ! #else ! close(csocket->fd); ! #endif csocket->fd=-1; return; } if (i==0) return; /* Don't have a full packet */ + /* Terminate the buffer */ csocket->inbuf.buf[csocket->inbuf.len]='\0'; data = (unsigned char *)strchr((char*)csocket->inbuf.buf +2, ' '); if (data) { *data='\0'; data++; } len = csocket->inbuf.len - (data - csocket->inbuf.buf); LOG(0,"Common::DoClient","Command:%s (%d)",csocket->inbuf.buf+2, len); for(i=0;i < NCOMMANDS;i++) { if (strcmp((char*)csocket->inbuf.buf+2,commands[i].cmdname)==0) { script_watch((char*)csocket->inbuf.buf+2,data,len,commands[i].cmdformat); commands[i].cmdproc(data,len); Index: common/newclient.h =================================================================== RCS file: /cvsroot/crossfire/client/common/newclient.h,v retrieving revision 1.7 diff -c -5 -r1.7 newclient.h *** common/newclient.h 19 Jan 2006 17:17:37 -0000 1.7 --- common/newclient.h 14 May 2006 13:04:43 -0000 *************** *** 47,60 **** #ifndef NEWCLIENT_H #define NEWCLIENT_H /* Maximum size of any packet we expect. Using this makes it so we don't need to ! * allocated and deallocated teh same buffer over and over again and the price ! * of using a bit of extra memory. IT also makes the code simpler. */ ! #define MAXSOCKBUF 10240 #define CS_QUERY_YESNO 0x1 /* Yes/no question */ #define CS_QUERY_SINGLECHAR 0x2 /* Single character response expected */ #define CS_QUERY_HIDEINPUT 0x4 /* Hide input being entered */ --- 47,62 ---- #ifndef NEWCLIENT_H #define NEWCLIENT_H /* Maximum size of any packet we expect. Using this makes it so we don't need to ! * allocate and deallocate the same buffer over and over again and the price ! * of using a bit of extra memory. It also makes the code simpler. ! * The size is big enough to receive any valid packet: 2 bytes for length, ! * 65535 for max. packet size, 1 for appended trailing '\0'. */ ! #define MAXSOCKBUF (2+65535+1) #define CS_QUERY_YESNO 0x1 /* Yes/no question */ #define CS_QUERY_SINGLECHAR 0x2 /* Single character response expected */ #define CS_QUERY_HIDEINPUT 0x4 /* Hide input being entered */ Index: common/newsocket.c =================================================================== RCS file: /cvsroot/crossfire/client/common/newsocket.c,v retrieving revision 1.14 diff -c -5 -r1.14 newsocket.c *** common/newsocket.c 23 Feb 2006 20:18:28 -0000 1.14 --- common/newsocket.c 14 May 2006 13:04:43 -0000 *************** *** 48,62 **** va_end(ap); #endif }*/ ! /* We don't care what these values are in the client, since ! * we toss them ! */ ! #define llevDebug 0 ! #define llevError 0 /* * This writes data to the socket. */ --- 48,59 ---- va_end(ap); #endif }*/ ! #define llevDebug LOG_DEBUG ! #define llevError LOG_ERROR /* * This writes data to the socket. */ *************** *** 164,178 **** short GetShort_String(const unsigned char *data) { return ((data[0]<<8)+data[1]); } ! /* this readsfrom fd and puts the data in sl. We return true if we think ! * we have a full packet, 0 if we have a partial packet. The only processing ! * we do is remove the intial size value. len (As passed) is the size of the ! * buffer allocated in the socklist. We make the assumption the buffer is ! * at least 2 bytes long. */ int SockList_ReadPacket(int fd, SockList *sl, int len) { int stat,toread,readsome=0; --- 161,175 ---- short GetShort_String(const unsigned char *data) { return ((data[0]<<8)+data[1]); } ! /* This reads from fd and puts the data in sl. We return true if we think we ! * have a full packet, 0 if we have a partial packet, or -1 if an error ! * occurred. The only processing we do is remove the initial size value. len ! * (As passed) is the size of the buffer allocated in the socklist. We make ! * the assumption the buffer is at least 2 bytes long. */ int SockList_ReadPacket(int fd, SockList *sl, int len) { int stat,toread,readsome=0;