mirror of
https://github.com/bgp/bgpq4
synced 2025-02-28 08:53:11 +00:00
ok, trying to get better sockbuf handling.
This commit is contained 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
|
||||
|
||||
@@ -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; c<recvbuffer+togot;) {
|
||||
size_t spn=strcspn(c," \n");
|
||||
@@ -426,7 +420,6 @@ bgpq_pipeline_dequeue(FILE* f, struct bgpq_expander* b)
|
||||
};
|
||||
|
||||
/* Final code */
|
||||
fseek(f,0,SEEK_END);
|
||||
if(fgets(recvbuffer,togot,f)==NULL) {
|
||||
if(ferror(f)) {
|
||||
sx_report(SX_FATAL,"Error reading RADB: %s (dequeue,final)"
|
||||
@@ -436,7 +429,6 @@ bgpq_pipeline_dequeue(FILE* f, struct bgpq_expander* b)
|
||||
};
|
||||
exit(1);
|
||||
};
|
||||
fseek(f,0,SEEK_END);
|
||||
} else if(request[0]=='C') {
|
||||
/* No data */
|
||||
} else if(request[0]=='D') {
|
||||
@@ -455,7 +447,6 @@ bgpq_pipeline_dequeue(FILE* f, struct bgpq_expander* b)
|
||||
b->piped--;
|
||||
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; c<recvbuffer+togot;) {
|
||||
size_t spn=strcspn(c," \n");
|
||||
@@ -528,7 +514,6 @@ bgpq_expand_radb(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
c+=spn+1;
|
||||
};
|
||||
|
||||
fseek(f,0,SEEK_END);
|
||||
if(fgets(recvbuffer,togot,f)==NULL) {
|
||||
if(feof(f)) {
|
||||
sx_report(SX_FATAL,"EOF from radb (expand,radb,final)\n");
|
||||
@@ -537,7 +522,6 @@ bgpq_expand_radb(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
};
|
||||
exit(1);
|
||||
};
|
||||
fseek(f,0,SEEK_END);
|
||||
} else if(request[0]=='C') {
|
||||
/* no data */
|
||||
} else if(request[0]=='D') {
|
||||
@@ -586,6 +570,7 @@ bgpq_expand(struct bgpq_expander* b)
|
||||
fd=-1;
|
||||
continue;
|
||||
};
|
||||
sx_maxsockbuf(fd,SO_SNDBUF);
|
||||
f=fdopen(fd,"a+");
|
||||
if(!f) {
|
||||
shutdown(fd,SHUT_RDWR);
|
||||
@@ -604,7 +589,6 @@ bgpq_expand(struct bgpq_expander* b)
|
||||
exit(1);
|
||||
};
|
||||
|
||||
fseek(f,0,SEEK_END);
|
||||
if((ret=fwrite("!!\n",1,3,f))!=3) {
|
||||
sx_report(SX_ERROR,"Partial fwrite to radb: %i bytes, %s\n",
|
||||
ret, strerror(errno));
|
||||
@@ -614,16 +598,13 @@ bgpq_expand(struct bgpq_expander* b)
|
||||
if(b->sources && 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);
|
||||
};
|
||||
|
||||
86
sx_maxsockbuf.c
Normal file
86
sx_maxsockbuf.c
Normal file
@@ -0,0 +1,86 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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<optval) {
|
||||
if(phase==0) {
|
||||
phase=1; optval>>=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;
|
||||
};
|
||||
8
sx_maxsockbuf.h
Normal file
8
sx_maxsockbuf.h
Normal file
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user