ip/torrent: limit number of connections

This commit is contained in:
cinap_lenrek 2012-05-06 16:33:17 +02:00
parent 7fff1f8dba
commit 8943c2fb8a

View file

@ -44,6 +44,8 @@ struct Stats
enum { enum {
MAXIO = 16*1024, MAXIO = 16*1024,
SRVPROCS = 16,
CLIPROCS = 16,
}; };
int debug; int debug;
@ -579,10 +581,11 @@ void
server(void) server(void)
{ {
char addr[64], adir[40], ldir[40]; char addr[64], adir[40], ldir[40];
int afd, lfd, dfd; int afd, lfd, dfd, pid, nprocs;
NetConnInfo *ni; NetConnInfo *ni;
afd = -1; afd = -1;
nprocs = 0;
for(port=6881; port<6890; port++){ for(port=6881; port<6890; port++){
snprint(addr, sizeof(addr), "tcp!*!%d", port); snprint(addr, sizeof(addr), "tcp!*!%d", port);
if((afd = announce(addr, adir)) >= 0) if((afd = announce(addr, adir)) >= 0)
@ -599,7 +602,13 @@ server(void)
fprint(2, "listen: %r"); fprint(2, "listen: %r");
break; break;
} }
if(rfork(RFFDG|RFPROC|RFMEM)){ while(nprocs >= SRVPROCS)
if(waitpid() > 0)
nprocs--;
nprocs++;
if(pid = rfork(RFFDG|RFPROC|RFMEM)){
if(pid < 0)
nprocs--;
close(lfd); close(lfd);
continue; continue;
} }
@ -610,16 +619,16 @@ server(void)
ni = getnetconninfo(ldir, dfd); ni = getnetconninfo(ldir, dfd);
peer(dfd, 1, ni ? ni->raddr : "???"); peer(dfd, 1, ni ? ni->raddr : "???");
if(ni) freenetconninfo(ni); if(ni) freenetconninfo(ni);
break; exits(0);
} }
exits(0);
} }
void void
client(char *ip, char *port) client(char *ip, char *port)
{ {
static Dict *peers; static Dict *peers, *peerqh, *peerqt;
static QLock peerslk; static QLock peerslk;
static int nprocs;
int try, fd; int try, fd;
char *addr; char *addr;
Dict *d; Dict *d;
@ -630,7 +639,7 @@ client(char *ip, char *port)
d = mallocz(sizeof(*d) + 64, 1); d = mallocz(sizeof(*d) + 64, 1);
snprint(addr = d->str, 64, "tcp!%s!%s", ip, port); snprint(addr = d->str, 64, "tcp!%s!%s", ip, port);
qlock(&peerslk); qlock(&peerslk);
if(dlook(peers, addr)){ if(dlook(peers, addr) || dlook(peerqh, addr)){
qunlock(&peerslk); qunlock(&peerslk);
free(d); free(d);
return; return;
@ -638,23 +647,44 @@ client(char *ip, char *port)
d->len = strlen(addr); d->len = strlen(addr);
d->typ = 'd'; d->typ = 'd';
d->val = d; d->val = d;
d->next = peers; d->next = nil;
peers = d; if(peerqt == nil)
peerqh = d;
else
peerqt->next = d;
peerqt = d;
if(nprocs >= CLIPROCS){
qunlock(&peerslk);
return;
}
nprocs++;
qunlock(&peerslk); qunlock(&peerslk);
if(debug) fprint(2, "client %s\n", addr); if(rfork(RFFDG|RFPROC|RFMEM|RFNOWAIT))
if(rfork(RFFDG|RFPROC|RFMEM))
return; return;
for(try = 0; try < 10; try++){ for(;;){
if((fd = dial(addr, nil, nil, nil)) >= 0){ qlock(&peerslk);
if(!peer(fd, 0, addr)) if(d = peerqh){
break; if((peerqh = d->next) == nil)
close(fd); peerqt = nil;
d->next = peers;
peers = d;
} else
nprocs--;
qunlock(&peerslk);
if(d == nil)
exits(0);
addr = d->str;
if(debug) fprint(2, "client %s\n", addr);
for(try = 0; try < 5; try++){
if((fd = dial(addr, nil, nil, nil)) >= 0){
if(!peer(fd, 0, addr))
break;
close(fd);
}
sleep((1000<<try)+nrand(5000));
} }
sleep((1000<<try)+nrand(5000));
} }
exits(0);
} }
int int