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;