X-Git-Url: http://git.dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Ffnet-dc.c;h=3fe49507f7994f5717180035db24181d7850a87d;hb=1e9d82b144bf3e6583ab78ca52d75c15f5d6f3fb;hp=d29514857587b6dd4299188dc50e9ff2a8e06171;hpb=69757b8cb02da682196de928a44dc991e07abad7;p=doldaconnect.git diff --git a/daemon/fnet-dc.c b/daemon/fnet-dc.c index d295148..3fe4950 100644 --- a/daemon/fnet-dc.c +++ b/daemon/fnet-dc.c @@ -128,6 +128,7 @@ struct dcpeer size_t inbufdata, inbufsize; size_t curread, totalsize; int freeing; + struct timer *timeout; struct qcommand *queue; struct transfer *transfer; int state; @@ -136,7 +137,7 @@ struct dcpeer int extended; int direction; /* Using the constants from transfer.h */ int compress; - int hascurpos, notthl; + int hascurpos, fetchingtthl, notthl; struct tigertreehash tth; void *cprsdata; char *key; @@ -444,6 +445,14 @@ static void hubrecvchat(struct socket *sk, struct fnetnode *fn, char *from, char free(chat); } +static void peertimeout(int cancelled, struct dcpeer *peer) +{ + peer->timeout = NULL; + if(cancelled) + return; + freedcpeer(peer); +} + static void sendadc(struct socket *sk, char *arg) { char *buf; @@ -676,6 +685,7 @@ static void requestfile(struct dcpeer *peer) sendadc(peer->sk, "0"); sendadc(peer->sk, "-1"); qstr(peer->sk, "|"); + peer->fetchingtthl = 1; return; } } @@ -1599,6 +1609,8 @@ static void cmd_key(struct socket *sk, struct dcpeer *peer, char *cmd, char *arg static void startdl(struct dcpeer *peer) { + if(peer->timeout != NULL) + canceltimer(peer->timeout); peer->state = PEER_TRNS; transferstartdl(peer->transfer, peer->sk); peer->sk->readcb = (void (*)(struct socket *, void *))transread; @@ -1607,6 +1619,8 @@ static void startdl(struct dcpeer *peer) static void startul(struct dcpeer *peer) { + if(peer->timeout != NULL) + canceltimer(peer->timeout); peer->state = PEER_TRNS; transferstartul(peer->transfer, peer->sk); peer->sk->writecb = (void (*)(struct socket *, void *))transwrite; @@ -1615,6 +1629,7 @@ static void startul(struct dcpeer *peer) static void cmd_filelength(struct socket *sk, struct dcpeer *peer, char *cmd, char *args) { int size; + struct transfer *transfer; if(peer->transfer == NULL) { @@ -1625,7 +1640,9 @@ static void cmd_filelength(struct socket *sk, struct dcpeer *peer, char *cmd, ch if(peer->transfer->size != size) { transfersetsize(peer->transfer, size); + transfer = peer->transfer; freedcpeer(peer); + trytransferbypeer(transfer->fnet, transfer->peerid); return; } startdl(peer); @@ -1634,6 +1651,13 @@ static void cmd_filelength(struct socket *sk, struct dcpeer *peer, char *cmd, ch static void cmd_error(struct socket *sk, struct dcpeer *peer, char *cmd, char *args) { + if(peer->fetchingtthl) + { + peer->fetchingtthl = 0; + peer->notthl = 1; + requestfile(peer); + return; + } if((peer->transfer != NULL) && (peer->transfer->dir == TRNSD_DOWN)) { transferseterror(peer->transfer, TRNSE_NOTFOUND); @@ -1767,15 +1791,10 @@ static void cmd_get(struct socket *sk, struct dcpeer *peer, char *cmd, char *arg } else if(fd >= 0) { if((buf2 = icsmbstowcs(args, DCCHARSET, NULL)) != NULL) transfersetpath(peer->transfer, buf2); + peer->transfer->flags.b.minislot = 1; } if(fd < 0) { - if(slotsleft() < 1) - { - qstr(sk, "$MaxedOut|"); - freedcpeer(peer); - return; - } if((node = resdcpath(args, DCCHARSET, '\\')) == NULL) { qstrf(sk, "$Error File not in share|"); @@ -1803,6 +1822,13 @@ static void cmd_get(struct socket *sk, struct dcpeer *peer, char *cmd, char *arg freedcpeer(peer); return; } + if(sb.st_size < 65536) + peer->transfer->flags.b.minislot = 1; + if(!peer->transfer->flags.b.minislot && (slotsleft() < 1)) { + qstr(sk, "$MaxedOut|"); + freedcpeer(peer); + return; + } if((offset != 0) && (lseek(fd, offset, SEEK_SET) < 0)) { close(fd); @@ -1906,14 +1932,10 @@ static void cmd_getblock(struct socket *sk, struct dcpeer *peer, char *cmd, char } else if(fd >= 0) { if((buf2 = icsmbstowcs(args, charset, NULL)) != NULL) transfersetpath(peer->transfer, buf2); + peer->transfer->flags.b.minislot = 1; } if(fd < 0) { - if(slotsleft() < 1) - { - qstr(sk, "$MaxedOut|"); - return; - } if((node = resdcpath(p, charset, '\\')) == NULL) { qstr(sk, "$Error File not in cache|"); @@ -1938,6 +1960,12 @@ static void cmd_getblock(struct socket *sk, struct dcpeer *peer, char *cmd, char qstr(sk, "$Error|"); return; } + if(sb.st_size < 65536) + peer->transfer->flags.b.minislot = 1; + if(!peer->transfer->flags.b.minislot && (slotsleft() < 1)) { + qstr(sk, "$MaxedOut|"); + return; + } if((start != 0) && ((start >= sb.st_size) || (lseek(fd, start, SEEK_SET) < 0))) { close(fd); @@ -1990,14 +2018,10 @@ static void cmd_adcget(struct socket *sk, struct dcpeer *peer, char *cmd, char * } else if(fd >= 0) { if((wbuf = icsmbstowcs(argv[1], "UTF-8", NULL)) != NULL) transfersetpath(peer->transfer, wbuf); + peer->transfer->flags.b.minislot = 1; } if(fd < 0) { - if(slotsleft() < 1) - { - qstr(sk, "$MaxedOut|"); - goto out; - } if(!strncmp(argv[1], "TTH/", 4)) { if((node = findbytth(argv[1] + 4)) == NULL) @@ -2037,6 +2061,12 @@ static void cmd_adcget(struct socket *sk, struct dcpeer *peer, char *cmd, char * qstr(sk, "$Error|"); goto out; } + if(sb.st_size < 65536) + peer->transfer->flags.b.minislot = 1; + if(!peer->transfer->flags.b.minislot && (slotsleft() < 1)) { + qstr(sk, "$MaxedOut|"); + goto out; + } if((start != 0) && ((start >= sb.st_size) || (lseek(fd, start, SEEK_SET) < 0))) { qstr(sk, "$Error Offset out of range|"); @@ -2100,6 +2130,8 @@ static void handletthl(struct dcpeer *peer) } if(peer->curread >= peer->totalsize) { + if(peer->timeout == NULL) + peer->timeout = timercallback(ntime() + 180, (void (*)(int, void *))peertimeout, peer); peer->state = PEER_CMD; synctigertree(&peer->tth); restigertree(&peer->tth, buf); @@ -2138,9 +2170,12 @@ static void cmd_adcsnd(struct socket *sk, struct dcpeer *peer, char *cmd, char * freedcpeer(peer); goto out; } + if(peer->timeout != NULL) + canceltimer(peer->timeout); peer->state = PEER_TTHL; peer->totalsize = numbytes; peer->curread = 0; + peer->fetchingtthl = 0; inittigertree(&peer->tth); handletthl(peer); } else if(!strcmp(argv[0], "file")) { @@ -2608,6 +2643,8 @@ static void dctransgotdata(struct transfer *transfer, struct dcpeer *peer) { freedcpeer(peer); } else { + if(peer->timeout == NULL) + peer->timeout = timercallback(ntime() + 180, (void (*)(int, void *))peertimeout, peer); peer->state = PEER_CMD; endcompress(peer); transfersetstate(transfer, TRNS_HS); @@ -2911,6 +2948,8 @@ static void freedcpeer(struct dcpeer *peer) resettransfer(peer->transfer); transferdetach(peer->transfer); } + if(peer->timeout != NULL) + canceltimer(peer->timeout); if(peer->sk->data == peer) peer->sk->data = NULL; peer->sk->readcb = NULL; @@ -3064,6 +3103,7 @@ static void peerconnect(struct socket *sk, int err, struct fnetnode *fn) sk->data = peer; socksettos(sk, confgetint("fnet", "fnptos")); putsock(sk); + peer->timeout = timercallback(ntime() + 180, (void (*)(int, void *))peertimeout, peer); sendmynick(peer); sendpeerlock(peer); } @@ -3078,6 +3118,7 @@ static void peeraccept(struct socket *sk, struct socket *newsk, void *data) newsk->errcb = (void (*)(struct socket *, int, void *))peererror; newsk->data = peer; socksettos(newsk, confgetint("fnet", "fnptos")); + peer->timeout = timercallback(ntime() + 180, (void (*)(int, void *))peertimeout, peer); } static void updatehmlist(void) @@ -3437,6 +3478,9 @@ static int run(void) nextpeer = peer->next; if((qcmd = ulqcmd(&peer->queue)) != NULL) { + if(peer->timeout != NULL) + canceltimer(peer->timeout); + peer->timeout = timercallback(ntime() + 180, (void (*)(int, void *))peertimeout, peer); if(*qcmd->string == '$') dispatchcommand(qcmd, peercmds, peer->sk, peer); freeqcmd(qcmd);