From 9a4cd7ee224fb1f3d9beb52f48eb7760efd4955a Mon Sep 17 00:00:00 2001 From: rswindell <> Date: Wed, 19 Dec 2012 12:37:19 +0000 Subject: [PATCH] Fix a (very) long-standing bug in sbbs_t::update_qwkroute(): was using static realloced variables for tracking QWKnet nodes discovered while importing msgs, but multiple terminal server nodes/events calling this function concurrently could clearly corrupt these variables and cause realloc errors and crashes. Now using members of sbbs_t for node/event instance specific QWKnet node tracking for the route.dat updates (a rarely used feature nowadays). --- src/sbbs3/main.cpp | 4 ++ src/sbbs3/qwk.cpp | 108 ++++++++++++--------------------------------- src/sbbs3/sbbs.h | 8 +++- 3 files changed, 39 insertions(+), 81 deletions(-) diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp index 83070cfbaf..1d8e41dcf7 100644 --- a/src/sbbs3/main.cpp +++ b/src/sbbs3/main.cpp @@ -3035,6 +3035,10 @@ sbbs_t::sbbs_t(ushort node_num, SOCKADDR_IN addr, const char* name, SOCKET sd, batdn_alt=NULL; batdn_cdt=NULL; + /* used by update_qwkroute(): */ + qwknode=NULL; + total_qwknodes=0; + spymsg("Connected"); } diff --git a/src/sbbs3/qwk.cpp b/src/sbbs3/qwk.cpp index e4328bb6ce..403212394b 100644 --- a/src/sbbs3/qwk.cpp +++ b/src/sbbs3/qwk.cpp @@ -8,7 +8,7 @@ * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2012 Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -187,10 +187,6 @@ int sbbs_t::qwk_route(char *inaddr, char *fulladdr) /* Via is in format: NODE/NODE/... */ void sbbs_t::update_qwkroute(char *via) { - static uint total_nodes; - static char **qwk_node; - static char **qwk_path; - static time_t *qwk_time; char str[256],*p,*tp,node[9]; uint i; int file; @@ -198,41 +194,26 @@ void sbbs_t::update_qwkroute(char *via) FILE * stream; if(via==NULL) { - if(!total_nodes) + if(!total_qwknodes) return; sprintf(str,"%sqnet/route.dat",cfg.data_dir); if((stream=fnopen(&file,str,O_WRONLY|O_CREAT|O_TRUNC))!=NULL) { t=time(NULL); t-=(90L*24L*60L*60L); - for(i=0;i<total_nodes;i++) - if(qwk_time[i]>t) + for(i=0;i<total_qwknodes;i++) + if(qwknode[i].time>t) fprintf(stream,"%s %s:%s\r\n" - ,unixtodstr(&cfg,(time32_t)qwk_time[i],str),qwk_node[i],qwk_path[i]); + ,unixtodstr(&cfg,(time32_t)qwknode[i].time,str),qwknode[i].id,qwknode[i].path); fclose(stream); } else errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC); - for(i=0;i<total_nodes;i++) { - free(qwk_node[i]); - free(qwk_path[i]); - } - if(qwk_node) { - free(qwk_node); - qwk_node=NULL; - } - if(qwk_path) { - free(qwk_path); - qwk_path=NULL; - } - if(qwk_time) { - free(qwk_time); - qwk_time=NULL; - } - total_nodes=0; + FREE_AND_NULL(qwknode); + total_qwknodes=0; return; } - if(!total_nodes) { + if(!total_qwknodes) { sprintf(str,"%sqnet/route.dat",cfg.data_dir); if((stream=fnopen(&file,str,O_RDONLY))!=NULL) { while(!feof(stream)) { @@ -246,39 +227,23 @@ void sbbs_t::update_qwkroute(char *via) sprintf(node,"%.8s",str+9); tp=strchr(node,' '); /* change "node bbs:" to "node:" */ if(tp) *tp=0; - for(i=0;i<total_nodes;i++) - if(!stricmp(qwk_node[i],node)) + for(i=0;i<total_qwknodes;i++) + if(!stricmp(qwknode[i].id,node)) break; - if(i<total_nodes && qwk_time[i]>t) + if(i<total_qwknodes && qwknode[i].time>t) continue; - if(i==total_nodes) { - if((qwk_node=(char **)realloc(qwk_node,sizeof(char *)*(i+1)))==NULL) { - errormsg(WHERE,ERR_ALLOC,str,9*(i+1)); - break; - } - if((qwk_path=(char **)realloc(qwk_path,sizeof(char *)*(i+1)))==NULL) { - errormsg(WHERE,ERR_ALLOC,str,sizeof(char*)*(i+1)); - break; - } - if((qwk_time=(time_t *)realloc(qwk_time,sizeof(time_t)*(i+1)))==NULL) { - errormsg(WHERE,ERR_ALLOC,str,sizeof(time_t)*(i+1)); - break; - } - if((qwk_node[i]=(char *)malloc(9))==NULL) { - errormsg(WHERE,ERR_ALLOC,str,9); - break; - } - if((qwk_path[i]=(char *)malloc(MAX_PATH+1))==NULL) { - errormsg(WHERE,ERR_ALLOC,str,MAX_PATH+1); + if(i==total_qwknodes) { + if((qwknode=(struct qwknode*)realloc(qwknode,sizeof(struct qwknode)*(i+1)))==NULL) { + errormsg(WHERE,ERR_ALLOC,str,sizeof(struct qwknode)*(i+1)); break; } - total_nodes++; + total_qwknodes++; } - strcpy(qwk_node[i],node); + strcpy(qwknode[i].id,node); p++; while(*p && *p<=' ') p++; - sprintf(qwk_path[i],"%.127s",p); - qwk_time[i]=t; + sprintf(qwknode[i].path,"%.127s",p); + qwknode[i].time=t; } fclose(stream); } @@ -296,39 +261,22 @@ void sbbs_t::update_qwkroute(char *via) tp=strchr(node,' '); /* no spaces allowed */ if(tp) *tp=0; truncsp(node); - for(i=0;i<total_nodes;i++) - if(!stricmp(qwk_node[i],node)) + for(i=0;i<total_qwknodes;i++) + if(!stricmp(qwknode[i].id,node)) break; - if(i==total_nodes) { /* Not in list */ - if((qwk_node=(char **)realloc(qwk_node,sizeof(char *)*(total_nodes+1)))==NULL) { - errormsg(WHERE,ERR_ALLOC,str,9*(total_nodes+1)); - break; - } - if((qwk_path=(char **)realloc(qwk_path,sizeof(char *)*(total_nodes+1)))==NULL) { - errormsg(WHERE,ERR_ALLOC,str,sizeof(char *)*(total_nodes+1)); + if(i==total_qwknodes) { /* Not in list */ + if((qwknode=(struct qwknode*)realloc(qwknode,sizeof(struct qwknode)*(total_qwknodes+1)))==NULL) { + errormsg(WHERE,ERR_ALLOC,str,sizeof(struct qwknode)*(total_qwknodes+1)); break; } - if((qwk_time=(time_t *)realloc(qwk_time,sizeof(time_t)*(total_nodes+1))) - ==NULL) { - errormsg(WHERE,ERR_ALLOC,str,sizeof(time_t)*(total_nodes+1)); - break; - } - if((qwk_node[total_nodes]=(char *)malloc(9))==NULL) { - errormsg(WHERE,ERR_ALLOC,str,9); - break; - } - if((qwk_path[total_nodes]=(char *)malloc(MAX_PATH+1))==NULL) { - errormsg(WHERE,ERR_ALLOC,str,MAX_PATH+1); - break; - } - total_nodes++; + total_qwknodes++; } - sprintf(qwk_node[i],"%.8s",node); - sprintf(qwk_path[i],"%.*s",(int)((p-1)-via),via); - qwk_time[i]=time(NULL); + sprintf(qwknode[i].id,"%.8s",node); + sprintf(qwknode[i].path,"%.*s",(int)((p-1)-via),via); + qwknode[i].time=time(NULL); p=strchr(p,'/'); } - } +} /****************************************************************************/ /* Successful download of QWK packet */ diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index cda7189d51..df3eb6e781 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -8,7 +8,7 @@ * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2012 Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -762,6 +762,12 @@ public: ulong qwkmail_last; void qwk_sec(void); int qwk_route(char *inaddr, char *fulladdr); + uint total_qwknodes; + struct qwknode { + char id[LEN_QWKID+1]; + char path[MAX_PATH+1]; + time_t time; + }* qwknode; void update_qwkroute(char *via); void qwk_success(ulong msgcnt, char bi, char prepack); void qwksetptr(uint subnum, char *buf, int reset); -- GitLab