From 483ca3e53f09862470f98d54ebb3c91c4bf77dd1 Mon Sep 17 00:00:00 2001 From: snar Date: Wed, 2 Jul 2008 17:02:34 +0000 Subject: [PATCH] ok, trying to get better sockbuf handling. --- Makefile.in | 4 +-- bgpq_expander.c | 29 +++-------------- sx_maxsockbuf.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ sx_maxsockbuf.h | 8 +++++ sx_report.c | 6 ++-- 5 files changed, 104 insertions(+), 29 deletions(-) create mode 100644 sx_maxsockbuf.c create mode 100644 sx_maxsockbuf.h diff --git a/Makefile.in b/Makefile.in index dd314ff..008a652 100644 --- a/Makefile.in +++ b/Makefile.in @@ -4,9 +4,9 @@ LDADD=@LDFLAGS@ @LIBS@ INSTALL=@INSTALL@ OBJECTS=bgpq3.o sx_report.o bgpq_expander.o sx_slentry.o bgpq3_printer.o \ - sx_prefix.o strlcpy.o + sx_prefix.o strlcpy.o sx_maxsockbuf.o SRCS=bgpq3.c sx_report.c bgpq_expander.c sx_slentry.c bgpq3_printer.c \ - sx_prefix.c strlcpy.c + sx_prefix.c strlcpy.c sx_maxsockbuf.c all: bgpq3 diff --git a/bgpq_expander.c b/bgpq_expander.c index ab020d4..ecea4c3 100644 --- a/bgpq_expander.c +++ b/bgpq_expander.c @@ -17,6 +17,7 @@ #include "bgpq3.h" #include "sx_report.h" +#include "sx_maxsockbuf.h" int debug_expander=0; int pipelining=1; @@ -239,7 +240,6 @@ bgpq_pipeline_dequeue_ripe(FILE* f, struct bgpq_expander* b) }; }; }; - fseek(f,0,SEEK_END); }; if(feof(f)) { sx_report(SX_FATAL,"EOF from RADB (dequeue, ripe)\n"); @@ -270,14 +270,11 @@ bgpq_expand_ripe(FILE* f, int (*callback)(char*, void*), void* udata, va_end(ap); SX_DEBUG(debug_expander,"expander(ripe): sending '%s'\n", request); - fseek(f,0,SEEK_END); fwrite(request,1,strlen(request),f); fflush(f); sawNL=0; - fseek(f,0,SEEK_END); while(fgets(request,sizeof(request),f)) { - fseek(f,0,SEEK_END); if(request[0]=='\n') { if(b->family==AF_INET && otype && !strcmp(otype,"route")) { SX_DEBUG(debug_expander,"expander(ripe): got route: %s\n", @@ -349,9 +346,7 @@ bgpq_pipeline(FILE* f, int (*callback)(char*, void*), void* udata, }; memset(bp,0,sizeof(bp)); - fseek(f,0,SEEK_END); ret=fwrite(request,1,strlen(request),f); - fseek(f,0,SEEK_END); if(ret!=strlen(request)) { sx_report(SX_FATAL,"Partial write to radb, only %i bytes written: %s\n", @@ -381,7 +376,6 @@ bgpq_pipeline_dequeue(FILE* f, struct bgpq_expander* b) char request[128]; struct bgpq_prequest* pipe; memset(request,0,sizeof(request)); - fseek(f,0,SEEK_END); if(!fgets(request,sizeof(request),f)) { if(ferror(f)) { sx_report(SX_FATAL,"Error reading data from RADB: %s (dequeue)" @@ -391,19 +385,18 @@ bgpq_pipeline_dequeue(FILE* f, struct bgpq_expander* b) }; exit(1); }; - fseek(f,0,SEEK_END); if(request[0]=='A') { char* eon, *c; unsigned long togot=strtoul(request+1,&eon,10); char recvbuffer[togot+2]; + memset(recvbuffer,0,togot+2); if(eon && *eon!='\n') { sx_report(SX_ERROR,"A-code finished with wrong char '%c'(%s)\n", *eon,request); exit(1); }; - fseek(f,0,SEEK_END); if(fgets(recvbuffer,togot+1,f)==NULL) { if(ferror(f)) { sx_report(SX_FATAL,"Error reading RADB: %s (dequeue, " @@ -413,7 +406,8 @@ bgpq_pipeline_dequeue(FILE* f, struct bgpq_expander* b) }; exit(1); }; - fseek(f,0,SEEK_END); + SX_DEBUG(debug_expander>=3,"Got %s in response to %s",recvbuffer, + b->firstpipe->request); for(c=recvbuffer; cpiped--; free(pipe); - fseek(f,0,SEEK_END); }; return 0; }; @@ -474,9 +465,7 @@ bgpq_expand_radb(FILE* f, int (*callback)(char*, void*), void* udata, SX_DEBUG(debug_expander,"expander: sending '%s'\n", request); - fseek(f,0,SEEK_END); ret=fwrite(request,1,strlen(request),f); - fseek(f,0,SEEK_END); if(ret!=strlen(request)) { sx_report(SX_FATAL,"Partial write to radb, only %i bytes written: %s\n", ret,strerror(errno)); @@ -494,7 +483,6 @@ bgpq_expand_radb(FILE* f, int (*callback)(char*, void*), void* udata, }; SX_DEBUG(debug_expander>2,"expander: initially got %i bytes, '%s'\n", strlen(request),request); - fseek(f,0,SEEK_END); if(request[0]=='A') { char* eon, *c; long togot=strtoul(request+1,&eon,10); @@ -506,7 +494,6 @@ bgpq_expand_radb(FILE* f, int (*callback)(char*, void*), void* udata, exit(1); }; - fseek(f,0,SEEK_END); if(fgets(recvbuffer,togot+1,f)==NULL) { if(feof(f)) { sx_report(SX_FATAL,"EOF from radb (expand,radb,result)\n"); @@ -518,7 +505,6 @@ bgpq_expand_radb(FILE* f, int (*callback)(char*, void*), void* udata, }; SX_DEBUG(debug_expander>2,"expander: final reply of %i bytes, '%s'\n", strlen(recvbuffer),recvbuffer); - fseek(f,0,SEEK_END); for(c=recvbuffer; csources && b->sources[0]!=0) { char sources[128]; snprintf(sources,sizeof(sources),"!s%s\n", b->sources); - fseek(f,0,SEEK_END); fwrite(sources,strlen(sources),1,f); - fseek(f,0,SEEK_END); fgets(sources,sizeof(sources),f); }; if(b->identify) { char ident[128]; snprintf(ident,sizeof(ident),"!n" PACKAGE_STRING "\n"); - fseek(f,0,SEEK_END); fwrite(ident,strlen(ident),1,f); fgets(ident,sizeof(ident),f); }; diff --git a/sx_maxsockbuf.c b/sx_maxsockbuf.c new file mode 100644 index 0000000..6912503 --- /dev/null +++ b/sx_maxsockbuf.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "sx_report.h" + +int +sx_maxsockbuf(int s, int dir) +{ + int optval=0, voptval; + int hiconf=-1, loconf=-1; + unsigned int voptlen; + int phase=0, iterations=0; + + if(s<0) { + sx_report(SX_FATAL,"Unable to maximize sockbuf on invalid socket %i\n", + s); + exit(1); + }; + + + voptlen=sizeof(optval); + if(getsockopt(s,SOL_SOCKET,dir,(void*)&optval,&voptlen)==-1) { + sx_report(SX_ERROR,"initial getsockopt failed: %s\n", strerror(errno)); + return -1; + }; + + for(;;) { + iterations++; + if(phase==0) optval<<=1; + else { + if(optval==(hiconf+loconf)/2) break; + optval=(hiconf+loconf)/2; + }; + if(optval>(2*1024*1024)) { + if(phase==0) { + phase=1; optval>>=1; continue; + } else break; + }; + + if(setsockopt(s,SOL_SOCKET,dir,(void*)&optval,sizeof(optval))==-1) + { + if(phase==0) phase=1; + hiconf=optval; + continue; + } else { + loconf=optval; + }; + + voptlen=sizeof(voptval); + + if(getsockopt(s,SOL_SOCKET,dir,(void*)&voptval,&voptlen)==-1) { + sx_report(SX_ERROR,"getsockopt failed: %s\n", strerror(errno)); + return -1; + } else { + if(voptval>=1; continue; + } else if(phase==1) { + phase=2; optval-=2048; continue; + } else break; + }; + }; + }; + + + voptlen=sizeof(voptval); + if(getsockopt(s,SOL_SOCKET,SO_RCVBUF,(void*)&voptval,&voptlen)==-1) { + sx_report(SX_ERROR,"getsockopt(final stage) failed: %s\n", + strerror(errno)); + return -1; + } else { + /* + printf("Finally got %i bytes of recvspace in %i interations\n", + voptval, iterations); + */ + }; + return 0; +}; diff --git a/sx_maxsockbuf.h b/sx_maxsockbuf.h new file mode 100644 index 0000000..be3efbb --- /dev/null +++ b/sx_maxsockbuf.h @@ -0,0 +1,8 @@ +#ifndef SX_MAXSOCKBUF_H_ +#define SX_MAXSOCKBUF_H_ + +/* s - number of opened socket, dir is either SO_SNDBUF or SO_RCVBUF */ +int sx_maxsockbuf(int s, int dir); + +#endif + diff --git a/sx_report.c b/sx_report.c index a7d92d4..eccc67e 100644 --- a/sx_report.c +++ b/sx_report.c @@ -31,7 +31,7 @@ sx_report_name(sx_report_t t) int sx_report(sx_report_t t, char* fmt, ...) { - char buffer[8192]; + char buffer[65536]; va_list ap; va_start(ap,fmt); @@ -68,8 +68,8 @@ int sx_debug(char const* const file, char const* const func, int const line, char* fmt, ...) { - char buffer[8192]; - char bline[8192]; + char buffer[65536]; + char bline[65536]; va_list ap; va_start(ap,fmt);