X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Ffnet-dc.c;h=d45b14489c9afa97d12aaacb0d31b985d2d1d680;hb=cab0b442977697b876127cda082b1262ece2714b;hp=804bd2c70838c955af73b717d89a284d8893d115;hpb=5ec60e4217863b0e2d6a86ba3f60f60c68608227;p=doldaconnect.git diff --git a/daemon/fnet-dc.c b/daemon/fnet-dc.c index 804bd2c..d45b144 100644 --- a/daemon/fnet-dc.c +++ b/daemon/fnet-dc.c @@ -160,13 +160,11 @@ static char *xmllistname = NULL; static char *xmlbz2listname = NULL; static struct timer *listwritetimer = NULL; -static int peerconnect(struct socket *sk, int err, struct fnetnode *fn); -static int peerread(struct socket *sk, struct dcpeer *peer); -static int peererror(struct socket *sk, int err, struct dcpeer *peer); +static void peerconnect(struct socket *sk, int err, struct fnetnode *fn); static void freedcpeer(struct dcpeer *peer); -static void transread(struct dcpeer *peer); -static void transerr(struct dcpeer *peer); -static int transwrite(struct socket *sk, struct dcpeer *peer); +static void transread(struct socket *sk, struct dcpeer *peer); +static void transerr(struct socket *sk, int err, struct dcpeer *peer); +static void transwrite(struct socket *sk, struct dcpeer *peer); static void updatehmlist(void); static void updatexmllist(void); static void updatexmlbz2list(void); @@ -1302,7 +1300,7 @@ static void cmd_connecttome(struct socket *sk, struct fnetnode *fn, char *cmd, c addr.sin_port = htons(atoi(p)); if(!inet_aton(args, &addr.sin_addr)) return; - newsk = netcsconn((struct sockaddr *)&addr, sizeof(addr), (int (*)(struct socket *, int, void *))peerconnect, fn); + newsk = netcsconn((struct sockaddr *)&addr, sizeof(addr), (void (*)(struct socket *, int, void *))peerconnect, fn); getfnetnode(fn); hubhandleaction(sk, fn, cmd, args); } @@ -1635,6 +1633,8 @@ static void startdl(struct dcpeer *peer) canceltimer(peer->timeout); peer->state = PEER_TRNS; transferstartdl(peer->transfer, peer->sk); + peer->sk->readcb = (void (*)(struct socket *, void *))transread; + peer->sk->errcb = (void (*)(struct socket *, int, void *))transerr; } static void startul(struct dcpeer *peer) @@ -1643,7 +1643,7 @@ static void startul(struct dcpeer *peer) canceltimer(peer->timeout); peer->state = PEER_TRNS; transferstartul(peer->transfer, peer->sk); - CBREG(peer->sk, socket_write, (int (*)(struct socket *, void *))transwrite, NULL, peer); + peer->sk->writecb = (void (*)(struct socket *, void *))transwrite; } static void cmd_filelength(struct socket *sk, struct dcpeer *peer, char *cmd, char *args) @@ -2215,7 +2215,12 @@ static void cmd_adcsnd(struct socket *sk, struct dcpeer *peer, char *cmd, char * goto out; } startdl(peer); - transread(peer); + if(peer->inbufdata > 0) + { + sockpushdata(sk, peer->inbuf, peer->inbufdata); + peer->inbufdata = 0; + transread(sk, peer); + } } else { /* We certainly didn't request this...*/ freedcpeer(peer); @@ -2243,7 +2248,12 @@ static void cmd_sending(struct socket *sk, struct dcpeer *peer, char *cmd, char return; } startdl(peer); - transread(peer); + if(peer->inbufdata > 0) + { + sockpushdata(sk, peer->inbuf, peer->inbufdata); + peer->inbufdata = 0; + transread(sk, peer); + } } /* @@ -2592,7 +2602,7 @@ static struct command peercmds[] = static void dctransdetach(struct transfer *transfer, struct dcpeer *peer) { - CBUNREG(transfer, trans_filterout, trresumecb, peer); + CBUNREG(transfer, trans_filterout, peer); if(peer->freeing) return; peer->transfer = NULL; @@ -2667,7 +2677,7 @@ static void dctransgotdata(struct transfer *transfer, struct dcpeer *peer) transfersetstate(transfer, TRNS_HS); socksettos(peer->sk, confgetint("fnet", "fnptos")); transfer->flags.b.minislot = 0; - CBUNREG(peer->sk, socket_write, transwrite, peer); + peer->sk->writecb = NULL; } } } @@ -2686,22 +2696,22 @@ static void dcwantdata(struct transfer *transfer, struct dcpeer *peer) peer->sk->ignread = 0; } -static void transread(struct dcpeer *peer) +static void transread(struct socket *sk, struct dcpeer *peer) { - size_t num; + void *buf; + size_t bufsize; struct transfer *transfer; + if((buf = sockgetinbuf(sk, &bufsize)) == NULL) + return; if(peer->transfer == NULL) { + free(buf); freedcpeer(peer); return; } - if(peer->inbufsize > peer->transfer->size - peer->transfer->curpos) - num = peer->transfer->size - peer->transfer->curpos; - else - num = peer->inbufsize; - transferputdata(peer->transfer, peer->inbuf, num); - memmove(peer->inbuf, peer->inbuf + num, peer->inbufsize -= num); + transferputdata(peer->transfer, buf, bufsize); + free(buf); if(peer->transfer->curpos >= peer->transfer->size) { transfer = peer->transfer; @@ -2710,33 +2720,35 @@ static void transread(struct dcpeer *peer) return; } if(transferdatasize(peer->transfer) > 65535) - peer->sk->ignread = 1; + sk->ignread = 1; } -static void transerr(struct dcpeer *peer) +static void transerr(struct socket *sk, int err, struct dcpeer *peer) { struct transfer *transfer; if((transfer = peer->transfer) == NULL) + { + freedcpeer(peer); return; + } transferdetach(transfer); transferendofdata(transfer); } -static int transwrite(struct socket *sk, struct dcpeer *peer) +static void transwrite(struct socket *sk, struct dcpeer *peer) { if((peer->state != PEER_TRNS) && (peer->state != PEER_SYNC)) - return(1); + return; if(peer->transfer == NULL) { freedcpeer(peer); - return(1); + return; } dctransgotdata(peer->transfer, peer); - return(0); } -static int udpread(struct socket *sk, void *data) +static void udpread(struct socket *sk, void *data) { char *buf, *p, *p2, *hashbuf; size_t buflen, hashlen; @@ -2750,7 +2762,7 @@ static int udpread(struct socket *sk, void *data) struct hash *hash; if((buf = sockgetinbuf(sk, &buflen)) == NULL) - return(0); + return; buf = srealloc(buf, buflen + 1); buf[buflen] = 0; if(!strncmp(buf, "$SR ", 4)) @@ -2760,7 +2772,7 @@ static int udpread(struct socket *sk, void *data) if((p2 = strchr(p, ' ')) == NULL) { free(buf); - return(0); + return; } *p2 = 0; p = p2 + 1; @@ -2768,14 +2780,14 @@ static int udpread(struct socket *sk, void *data) if((p2 = strchr(p, 5)) == NULL) { free(buf); - return(0); + return; } *p2 = 0; p = p2 + 1; if((p2 = strchr(p, ' ')) == NULL) { free(buf); - return(0); + return; } *p2 = 0; size = atoi(p); @@ -2783,7 +2795,7 @@ static int udpread(struct socket *sk, void *data) if((p2 = strchr(p, '/')) == NULL) { free(buf); - return(0); + return; } *p2 = 0; slots = atoi(p); @@ -2791,34 +2803,34 @@ static int udpread(struct socket *sk, void *data) if((p2 = strchr(p, 5)) == NULL) { free(buf); - return(0); + return; } p = p2 + 1; hubname = p; if((p2 = strstr(p, " (")) == NULL) { free(buf); - return(0); + return; } *p2 = 0; p = p2 + 2; if((p2 = strchr(p, ':')) == NULL) { free(buf); - return(0); + return; } *(p2++) = 0; hubaddr.sin_family = AF_INET; if(!inet_aton(p, &hubaddr.sin_addr)) { free(buf); - return(0); + return; } p = p2; if((p2 = strchr(p, ')')) == NULL) { free(buf); - return(0); + return; } *p2 = 0; hubaddr.sin_port = htons(atoi(p)); @@ -2826,7 +2838,7 @@ static int udpread(struct socket *sk, void *data) if((wfile = icmbstowcs(filename, DCCHARSET)) == NULL) { free(buf); - return(0); + return; } myfn = NULL; hash = NULL; @@ -2873,7 +2885,7 @@ static int udpread(struct socket *sk, void *data) if((wnick = icmbstowcs(nick, (hub == NULL)?DCCHARSET:(hub->charset))) == NULL) { free(buf); - return(0); + return; } sr = newsrchres(&dcnet, wfile, wnick); if(sr->peernick != NULL) @@ -2891,7 +2903,6 @@ static int udpread(struct socket *sk, void *data) freesrchres(sr); } free(buf); - return(0); } static void hubread(struct socket *sk, struct fnetnode *fn) @@ -3033,9 +3044,11 @@ static void freedcpeer(struct dcpeer *peer) } if(peer->timeout != NULL) canceltimer(peer->timeout); - /* XXX: Unregister transwrite from peer->sk->socket_write? */ - CBUNREG(peer->sk, socket_read, peerread, peer); - CBUNREG(peer->sk, socket_err, peererror, peer); + if(peer->sk->data == peer) + peer->sk->data = NULL; + peer->sk->readcb = NULL; + peer->sk->writecb = NULL; + peer->sk->errcb = NULL; putsock(peer->sk); endcompress(peer); if(peer->supports != NULL) @@ -3064,9 +3077,11 @@ static void freedcpeer(struct dcpeer *peer) static void hubconnect(struct fnetnode *fn) { - CBREG(fn->sk, socket_read, (int (*)(struct socket *, void *))hubread, (void (*)(void *))putfnetnode, getfnetnode(fn)); - CBREG(fn->sk, socket_err, (int (*)(struct socket *, int, void *))huberr, (void (*)(void *))putfnetnode, getfnetnode(fn)); + fn->sk->readcb = (void (*)(struct socket *, void *))hubread; + fn->sk->errcb = (void (*)(struct socket *, int, void *))huberr; + getfnetnode(fn); fn->data = newdchub(fn); + fn->sk->data = fn; return; } @@ -3076,10 +3091,10 @@ static void hubdestroy(struct fnetnode *fn) struct qcommand *qcmd; hub = (struct dchub *)fn->data; - if(fn->sk != NULL) + if((fn->sk != NULL) && (fn->sk->data == fn)) { - CBUNREG(fn->sk, socket_read, hubread, fn); - CBUNREG(fn->sk, socket_err, huberr, fn); + fn->sk->data = NULL; + putfnetnode(fn); } if(hub == NULL) return; @@ -3125,61 +3140,48 @@ static struct fnet dcnet = .filebasename = dcbasename }; -static void cmdread(struct dcpeer *peer) +static void peerread(struct socket *sk, struct dcpeer *peer) { - char *p; - struct command *cmd; - - p = peer->inbuf; - while((peer->inbufdata > 0) && (p = memchr(peer->inbuf, '|', peer->inbufdata)) != NULL) - { - *(p++) = 0; - newqcmd(&peer->queue, peer->inbuf); - for(cmd = peercmds; cmd->handler != NULL; cmd++) - { - if(!memcmp(peer->inbuf, cmd->name, strlen(cmd->name)) && ((peer->inbuf[strlen(cmd->name)] == ' ') || (peer->inbuf[strlen(cmd->name)] == '|'))) - break; - } - memmove(peer->inbuf, p, peer->inbufdata -= p - peer->inbuf); - if(cmd->stop) - { - peer->state = PEER_STOP; - break; - } - } -} - -static int peerread(struct socket *sk, struct dcpeer *peer) -{ - char *newbuf; + char *newbuf, *p; size_t datalen; + struct command *cmd; if((newbuf = sockgetinbuf(sk, &datalen)) == NULL) - return(0); + return; sizebuf2(peer->inbuf, peer->inbufdata + datalen, 1); memcpy(peer->inbuf + peer->inbufdata, newbuf, datalen); free(newbuf); peer->inbufdata += datalen; if(peer->state == PEER_CMD) { - cmdread(peer); - } else if(peer->state == PEER_TRNS) { - transread(peer); + p = peer->inbuf; + while((peer->inbufdata > 0) && (p = memchr(peer->inbuf, '|', peer->inbufdata)) != NULL) + { + *(p++) = 0; + newqcmd(&peer->queue, peer->inbuf); + for(cmd = peercmds; cmd->handler != NULL; cmd++) + { + if(!memcmp(peer->inbuf, cmd->name, strlen(cmd->name)) && ((peer->inbuf[strlen(cmd->name)] == ' ') || (peer->inbuf[strlen(cmd->name)] == '|'))) + break; + } + memmove(peer->inbuf, p, peer->inbufdata -= p - peer->inbuf); + if(cmd->stop) + { + peer->state = PEER_STOP; + break; + } + } } else if(peer->state == PEER_TTHL) { handletthl(peer); } - return(0); } -static int peererror(struct socket *sk, int err, struct dcpeer *peer) +static void peererror(struct socket *sk, int err, struct dcpeer *peer) { - if(peer->state == PEER_TRNS) - transerr(peer); freedcpeer(peer); - return(0); } -static int peerconnect(struct socket *sk, int err, struct fnetnode *fn) +static void peerconnect(struct socket *sk, int err, struct fnetnode *fn) { struct dcpeer *peer; struct dchub *hub; @@ -3188,34 +3190,34 @@ static int peerconnect(struct socket *sk, int err, struct fnetnode *fn) { putfnetnode(fn); putsock(sk); - return(1); + return; } hub = fn->data; peer = newdcpeer(sk); peer->fn = fn; peer->accepted = 0; peer->dcppemu = hub->dcppemu; - CBREG(sk, socket_read, (int (*)(struct socket *, void *))peerread, NULL, peer); - CBREG(sk, socket_err, (int (*)(struct socket *, int, void *))peererror, NULL, peer); + sk->readcb = (void (*)(struct socket *, void *))peerread; + sk->errcb = (void (*)(struct socket *, int, void *))peererror; + sk->data = peer; socksettos(sk, confgetint("fnet", "fnptos")); putsock(sk); peer->timeout = timercallback(ntime() + 180, (void (*)(int, void *))peertimeout, peer); sendmynick(peer); sendpeerlock(peer); - return(1); } -static int peeraccept(struct socket *sk, struct socket *newsk, void *data) +static void peeraccept(struct socket *sk, struct socket *newsk, void *data) { struct dcpeer *peer; peer = newdcpeer(newsk); peer->accepted = 1; - CBREG(sk, socket_read, (int (*)(struct socket *, void *))peerread, NULL, peer); - CBREG(sk, socket_err, (int (*)(struct socket *, int, void *))peererror, NULL, peer); + newsk->readcb = (void (*)(struct socket *, void *))peerread; + 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); - return(0); } static void updatehmlist(void) @@ -3633,7 +3635,7 @@ static int updateudpport(struct configvar *var, void *uudata) flog(LOG_WARNING, "could not create new DC UDP socket, reverting to old: %s", strerror(errno)); return(0); } - CBREG(newsock, socket_read, udpread, NULL, NULL); + newsock->readcb = udpread; if(udpsock != NULL) putsock(udpsock); udpsock = newsock; @@ -3675,7 +3677,7 @@ static int init(int hup) flog(LOG_CRIT, "could not create DC UDP socket: %s", strerror(errno)); return(1); } - CBREG(udpsock, socket_read, udpread, NULL, NULL); + udpsock->readcb = udpread; addr.sin_port = htons(confgetint("dc", "tcpport")); if((tcpsock = netcslisten(SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr), peeraccept, NULL)) == NULL) flog(LOG_INFO, "could not listen to a remote address, going into passive mode");