diff options
author | TAW Dev <tawdev@taw> | 2009-07-08 11:04:59 -0400 |
---|---|---|
committer | TAW Dev <tawdev@taw> | 2009-07-08 11:04:59 -0400 |
commit | aa0bb68d762f72d8abb2b71079e98a8e27969412 (patch) | |
tree | 77e38010cc0443cc7480572e823dd13ee7ee555d /src/common | |
parent | e9c1a79b6306783d63655eca5ddbcca0b6d825d0 (diff) | |
parent | 4673fd3ca06010e74f8223486b0f34e58c7b0a7e (diff) | |
download | tmwa-aa0bb68d762f72d8abb2b71079e98a8e27969412.tar.gz tmwa-aa0bb68d762f72d8abb2b71079e98a8e27969412.tar.bz2 tmwa-aa0bb68d762f72d8abb2b71079e98a8e27969412.tar.xz tmwa-aa0bb68d762f72d8abb2b71079e98a8e27969412.zip |
Merge branch 'master' of git://gitorious.org/tmw-eathena/mainline
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/grfio.c | 39 | ||||
-rw-r--r-- | src/common/lock.c | 7 | ||||
-rw-r--r-- | src/common/socket.c | 65 | ||||
-rw-r--r-- | src/common/socket.h | 16 |
4 files changed, 104 insertions, 23 deletions
diff --git a/src/common/grfio.c b/src/common/grfio.c index 08a8b2a..b5f380c 100644 --- a/src/common/grfio.c +++ b/src/common/grfio.c @@ -30,6 +30,7 @@ #include "utils.h" #include "grfio.h" #include "mmo.h" +#include "socket.h" #ifdef MEMWATCH #include "memwatch.h" @@ -414,7 +415,7 @@ char* grfio_resnametable(char* fname, char *lfname) for(p=&restable[0];*p!=0;p++) if (*p=='\\') *p = '/'; - fp = fopen(restable,"rb"); + fp = fopen_(restable,"rb"); if(fp==NULL) { printf("%s not found\n",restable); exit(1); // 1:not found error @@ -423,11 +424,11 @@ char* grfio_resnametable(char* fname, char *lfname) while(fgets(line,508,fp)){ if((sscanf(line,"%[^#]#%[^#]#",w1,w2)==2) && (sscanf(fname,"%*5s%s",lfname)==1) && (!strcmpi(w1,lfname))){ sprintf(lfname,"data\\%s",w2); - fclose(fp); + fclose_(fp); return lfname; } } - fclose(fp); + fclose_(fp); return fname; } @@ -493,7 +494,7 @@ void* grfio_reads(char *fname, int *size) for(p=&lfname[0];*p!=0;p++) if (*p=='\\') *p = '/'; // * At the time of Unix - in = fopen(lfname,"rb"); + in = fopen_(lfname,"rb"); if(in!=NULL) { if (entry!=NULL && entry->gentry==0) { lentry.declen=entry->declen; @@ -508,7 +509,7 @@ void* grfio_reads(char *fname, int *size) goto errret; } fread(buf2,1,lentry.declen,in); - fclose(in); in = NULL; + fclose_(in); in = NULL; strncpy( lentry.fn, fname, sizeof(lentry.fn)-1 ); lentry.gentry = 0; // 0:LocalFile entry = filelist_modify(&lentry); @@ -530,7 +531,7 @@ void* grfio_reads(char *fname, int *size) goto errret; } gfname = gentry_table[entry->gentry-1]; - in = fopen(gfname,"rb"); + in = fopen_(gfname,"rb"); if(in==NULL) { printf("%s not found\n",gfname); //goto errret; @@ -539,7 +540,7 @@ void* grfio_reads(char *fname, int *size) } fseek(in,entry->srcpos,0); fread(buf,1,entry->srclen_aligned,in); - fclose(in); + fclose_(in); buf2=calloc(entry->declen+1024, 1); if (buf2==NULL) { printf("file decode memory allocate error\n"); @@ -567,7 +568,7 @@ void* grfio_reads(char *fname, int *size) errret: if (buf!=NULL) free(buf); if (buf2!=NULL) free(buf2); - if (in!=NULL) fclose(in); + if (in!=NULL) fclose_(in); exit(1); //return NULL; } @@ -609,7 +610,7 @@ static int grfio_entryread(char *gfname,int gentry) unsigned char *fname; unsigned char *grf_filelist; - fp = fopen(gfname,"rb"); + fp = fopen_(gfname,"rb"); if(fp==NULL) { printf("%s not found\n",gfname); return 1; // 1:not found error @@ -620,7 +621,7 @@ static int grfio_entryread(char *gfname,int gentry) fseek(fp,0,0); // SEEK_SET fread(grf_header,1,0x2e,fp); if(strcmp(grf_header,"Master of Magic") || fseek(fp,getlong(grf_header+0x1e),1)){ // SEEK_CUR - fclose(fp); + fclose_(fp); printf("%s read error\n",gfname); return 2; // 2:file format error } @@ -631,12 +632,12 @@ static int grfio_entryread(char *gfname,int gentry) list_size = grf_size-ftell(fp); grf_filelist = calloc(list_size, 1); if(grf_filelist==NULL){ - fclose(fp); + fclose_(fp); printf("out of memory : grf_filelist\n"); return 3; // 3:memory alloc error } fread(grf_filelist,1,list_size,fp); - fclose(fp); + fclose_(fp); entrys = getlong(grf_header+0x26) - getlong(grf_header+0x22) - 7; @@ -699,26 +700,26 @@ static int grfio_entryread(char *gfname,int gentry) eSize = getlong(eheader+4); // Extend Size if (rSize > grf_size-ftell(fp)) { - fclose(fp); + fclose_(fp); printf("Illegal data format : grf compress entry size\n"); return 4; } rBuf = calloc( rSize , 1); // Get a Read Size if (rBuf==NULL) { - fclose(fp); + fclose_(fp); printf("out of memory : grf compress entry table buffer\n"); return 3; } grf_filelist = calloc( eSize , 1); // Get a Extend Size if (grf_filelist==NULL) { free(rBuf); - fclose(fp); + fclose_(fp); printf("out of memory : grf extract entry table buffer\n"); return 3; } fread(rBuf,1,rSize,fp); - fclose(fp); + fclose_(fp); decode_zip(grf_filelist,&eSize,rBuf,rSize); // Decode function list_size = eSize; free(rBuf); @@ -767,7 +768,7 @@ static int grfio_entryread(char *gfname,int gentry) free(grf_filelist); } else { //****** Grf Other version ****** - fclose(fp); + fclose_(fp); printf("not support grf versions : %04x\n",getlong(grf_header+0x2a)); return 4; } @@ -903,7 +904,7 @@ void grfio_init(char *fname) char line[1024], w1[1024], w2[1024]; int result = 0, result2 = 0, result3 = 0; - data_conf = fopen(fname, "r"); + data_conf = fopen_(fname, "r"); // It will read, if there is grf-files.txt. if (data_conf) { @@ -920,7 +921,7 @@ void grfio_init(char *fname) } } - fclose(data_conf); + fclose_(data_conf); printf("read %s done\n",fname); } // end of reading grf-files.txt diff --git a/src/common/lock.c b/src/common/lock.c index 9a2205b..67001f9 100644 --- a/src/common/lock.c +++ b/src/common/lock.c @@ -1,6 +1,7 @@ #include <stdio.h> #include "lock.h" +#include "socket.h" // 書き込みファイルの保護処理 // (書き込みが終わるまで、旧ファイルを保管しておく) @@ -14,9 +15,9 @@ FILE* lock_fopen(const char* filename,int *info) { // 安全なファイル名を得る(手抜き) do { sprintf(newfile,"%s_%04d.tmp",filename,++no); - } while((fp = fopen(newfile,"r")) && (fclose(fp), no<9999) ); + } while((fp = fopen_(newfile,"r")) && (fclose_(fp), no<9999) ); *info = no; - return fopen(newfile,"w"); + return fopen_(newfile,"w"); } // 旧ファイルを削除&新ファイルをリネーム @@ -24,7 +25,7 @@ int lock_fclose(FILE *fp,const char* filename,int *info) { int ret = 0; char newfile[512]; if(fp != NULL) { - ret = fclose(fp); + ret = fclose_(fp); sprintf(newfile,"%s_%04d.tmp",filename,*info); remove(filename); // このタイミングで落ちると最悪。 diff --git a/src/common/socket.c b/src/common/socket.c index f968373..886072e 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -4,6 +4,7 @@ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> +#include <errno.h> #ifdef LCCWIN32 #define WIN32_LEAN_AND_MEAN @@ -30,6 +31,7 @@ fd_set readfds; int fd_max; +int currentuse; int rfifo_size = 65536; int wfifo_size = 65536; @@ -74,6 +76,7 @@ static int recv_to_fifo(int fd) //{ int i; printf("recv %d : ",fd); for(i=0;i<len;i++){ printf("%02x ",RFIFOB(fd,session[fd]->rdata_size+i)); } printf("\n");} if(len>0){ session[fd]->rdata_size+=len; + if (!session[fd]->connected) session[fd]->connected = 1; } else if(len<=0){ // value of connection is not necessary the same // if (fd == 4) // Removed [Yor] @@ -117,6 +120,7 @@ static int send_from_fifo(int fd) } else { session[fd]->wdata_size=0; } + if (!session[fd]->connected) session[fd]->connected = 1; } else { printf("set eof :%d\n",fd); session[fd]->eof=1; @@ -146,6 +150,8 @@ static int connect_client(int listen_fd) //printf("connect_client : %d\n",listen_fd); + printf("used: %d, max FDs: %d, SOFT: %d\n", currentuse, FD_SETSIZE, SOFT_LIMIT); + len = sizeof(client_address); fd = accept(listen_fd,(struct sockaddr*)&client_address,&len); @@ -155,6 +161,11 @@ static int connect_client(int listen_fd) perror("accept"); return -1; } + if (!free_fds()) { // gracefully end the connecting if no free FD + printf("softlimit reached, disconnecting : %d\n", fd); + delete_session(fd); + return -1; + } // setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,NULL,0); setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof yes); // reuse fix @@ -186,6 +197,10 @@ static int connect_client(int listen_fd) session[fd]->func_send = send_from_fifo; session[fd]->func_parse = default_func_parse; session[fd]->client_addr = client_address; + session[fd]->created = time(NULL); + session[fd]->connected = 0; + + currentuse++; //printf("new_session : %d %d\n",fd,session[fd]->eof); return fd; @@ -200,6 +215,10 @@ int make_listen_port(int port) fd = socket( AF_INET, SOCK_STREAM, 0 ); if(fd_max<=fd) fd_max=fd+1; + else if (fd == -1) { + perror("connect"); + return -1; + } #ifdef LCCWIN32 { @@ -244,7 +263,10 @@ int make_listen_port(int port) } memset(session[fd],0,sizeof(*session[fd])); session[fd]->func_recv = connect_client; + session[fd]->created = time(NULL); + session[fd]->connected = 1; + currentuse++; return fd; } @@ -257,6 +279,11 @@ int make_connection(long ip,int port) fd = socket( AF_INET, SOCK_STREAM, 0 ); if(fd_max<=fd) fd_max=fd+1; + else if (fd == -1) { + perror("socket"); + return -1; + } + // setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,NULL,0); setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof yes); // reuse fix #ifdef SO_REUSEPORT @@ -292,7 +319,10 @@ int make_connection(long ip,int port) session[fd]->func_recv = recv_to_fifo; session[fd]->func_send = send_from_fifo; session[fd]->func_parse = default_func_parse; + session[fd]->created = time(NULL); + session[fd]->connected = 1; + currentuse++; return fd; } @@ -311,6 +341,13 @@ int delete_session(int fd) free(session[fd]); } session[fd]=NULL; + shutdown(fd, SHUT_RDWR); + close(fd); + currentuse--; + if (currentuse<0) { + printf("delete_session: current sessions negative!\n"); + currentuse=0; + } //printf("delete_session:%d\n",fd); return 0; } @@ -390,6 +427,10 @@ int do_parsepacket(void) for(i=0;i<fd_max;i++){ if(!session[i]) continue; + if(!session[i]->connected && time(NULL)-session[i]->created > CONNECT_TIMEOUT) { + printf("Session #%d timed out\n", i); + session[i]->eof = 1; + } if(session[i]->rdata_size==0 && session[i]->eof==0) continue; if(session[i]->func_parse){ @@ -405,6 +446,7 @@ int do_parsepacket(void) void do_socket(void) { FD_ZERO(&readfds); + currentuse = 2; } int RFIFOSKIP(int fd,int len) @@ -438,3 +480,26 @@ int Net_Init(void) return(0); } +int fclose_(FILE *fp) +{ + int res = fclose(fp); + if (res == 0) + currentuse--; +// printf("file closed: used: %d\n",currentuse); + return res; +} + +FILE *fopen_(const char *path, const char *mode) +{ + FILE *f = fopen(path, mode); + if (f != NULL) + currentuse++; +// printf("file opened: used: %d\n",currentuse); + return f; +} + +int free_fds() +{ + return (currentuse+1 < SOFT_LIMIT) ? 1 : 0; +} + diff --git a/src/common/socket.h b/src/common/socket.h index fe06e40..b67e660 100644 --- a/src/common/socket.h +++ b/src/common/socket.h @@ -12,6 +12,7 @@ #include <sys/socket.h> #include <netinet/in.h> #endif +#include <time.h> // define declaration @@ -44,13 +45,14 @@ #define FD_SETSIZE 4096 #endif // __INTERIX - /* Removed Cygwin FD_SETSIZE declarations, now are directly passed on to the compiler through Makefile [Valaris] */ // Struct declaration struct socket_data{ int eof; + time_t created; + int connected; unsigned char *rdata,*wdata; int max_rdata,max_wdata; int rdata_size,wdata_size; @@ -71,6 +73,13 @@ struct socket_data{ #endif +// save file descriptors for important stuff +#define SOFT_LIMIT (FD_SETSIZE - 50) + +// socket timeout to establish a full connection in seconds +#define CONNECT_TIMEOUT 15 + + extern struct socket_data *session[FD_SETSIZE]; extern int rfifo_size,wfifo_size; @@ -93,4 +102,9 @@ void set_defaultparse(int (*defaultparse)(int)); int Net_Init(void); +int fclose_(FILE *fp); +FILE *fopen_(const char *path, const char *mode); + +int free_fds(); + #endif // _SOCKET_H_ |