X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Ffnet-dc.c;h=7cbb32ea45a8d370b0900d574ccae2f15cd376f3;hb=ddb3658e4a9d9efb7a8628fee483e5371c426d12;hp=804bd2c70838c955af73b717d89a284d8893d115;hpb=5ec60e4217863b0e2d6a86ba3f60f60c68608227;p=doldaconnect.git diff --git a/daemon/fnet-dc.c b/daemon/fnet-dc.c index 804bd2c..7cbb32e 100644 --- a/daemon/fnet-dc.c +++ b/daemon/fnet-dc.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -160,13 +159,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); @@ -730,7 +727,7 @@ static void requestfile(struct dcpeer *peer) freedcpeer(peer); return; } - qstrf(peer->sk, "$UGetBlock %i %i %s|", peer->transfer->curpos, peer->transfer->size - peer->transfer->curpos, buf); + qstrf(peer->sk, "$UGetBlock %zi %zi %s|", peer->transfer->curpos, peer->transfer->size - peer->transfer->curpos, buf); } else { /* Use DCCHARSET for $Get paths until further researched... */ if((buf = icswcstombs(peer->transfer->path, DCCHARSET, NULL)) == NULL) @@ -739,7 +736,7 @@ static void requestfile(struct dcpeer *peer) freedcpeer(peer); return; } - qstrf(peer->sk, "$Get %s$%i|", buf, peer->transfer->curpos + 1); + qstrf(peer->sk, "$Get %s$%zi|", buf, peer->transfer->curpos + 1); } } @@ -1233,10 +1230,10 @@ static void cmd_search(struct socket *sk, struct fnetnode *fn, char *cmd, char * if(node->f.b.hastth) { buf2 = base32encode(node->hashtth, 24); - qstrf(dsk, "%s%s\005%i%sTTH:%.39s%s", prefix, buf, node->size, infix, buf2, postfix); + qstrf(dsk, "%s%s\005%zi%sTTH:%.39s%s", prefix, buf, node->size, infix, buf2, postfix); free(buf2); } else { - qstrf(dsk, "%s%s\005%i%s%s%s", prefix, buf, node->size, infix, hub->nativename, postfix); + qstrf(dsk, "%s%s\005%zi%s%s%s", prefix, buf, node->size, infix, hub->nativename, postfix); } free(buf); } @@ -1302,7 +1299,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 +1632,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 +1642,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) @@ -1861,7 +1860,7 @@ static void cmd_get(struct socket *sk, struct dcpeer *peer, char *cmd, char *arg lesk = wrapsock(fd); transferprepul(peer->transfer, sb.st_size, offset, -1, lesk); putsock(lesk); - qstrf(sk, "$FileLength %i|", peer->transfer->size); + qstrf(sk, "$FileLength %zi|", peer->transfer->size); } static void cmd_send(struct socket *sk, struct dcpeer *peer, char *cmd, char *args) @@ -2215,7 +2214,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 +2247,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 +2601,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 +2676,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 +2695,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 +2719,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 +2761,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 +2771,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 +2779,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 +2794,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 +2802,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 +2837,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 +2884,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 +2902,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 +3043,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 +3076,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 +3090,12 @@ 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; + fn->sk->readcb = NULL; + fn->sk->errcb = NULL; + putfnetnode(fn); } if(hub == NULL) return; @@ -3125,61 +3141,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 +3191,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) @@ -3243,7 +3246,7 @@ static void updatehmlist(void) if(node->f.b.type == FILE_REG) { addtobuf(buf, '|'); - sprintf(numbuf, "%i", node->size); + sprintf(numbuf, "%zi", node->size); bufcat(buf, numbuf, strlen(numbuf)); } addtobuf(buf, 13); @@ -3418,7 +3421,7 @@ static void updatexmllist(void) lev++; continue; } else { - fprintf(fs, "size); + fprintf(fs, "size); if(node->f.b.hastth) { hashbuf = base32encode(node->hashtth, 24); @@ -3528,7 +3531,7 @@ static void updatelists(int now) if(!now) { if(listwritetimer == NULL) - listwritetimer = timercallback(ntime() + 300, listtimercb, NULL); + listwritetimer = timercallback(ntime() + confgetint("cli", "hashwritedelay"), listtimercb, NULL); return; } if(listwritetimer != NULL) @@ -3633,7 +3636,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 +3678,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"); @@ -3707,11 +3710,31 @@ static void terminate(void) static struct configvar myvars[] = { + /** Specifies the share description reported to other DC users. */ {CONF_VAR_STRING, "desc", {.str = L""}}, + /** Specifies the speed reported to other DC users. Normal values + * are 28.8Kbps, 33.6Kbps, 56Kbps, Satellite, ISDN, DSL, Cable, + * LAN(T1) or LAN(T3)*/ {CONF_VAR_STRING, "speedstring", {.str = L"LAN(T1)"}}, + /** The e-mail address to report to other DC users. */ {CONF_VAR_STRING, "email", {.str = L"spam@spam.org"}}, + /** Specifies a specific UDP port to use for DC search results. If + * left unspecified, a port is allocated dynamically. Useful for + * NAT routers (see also the net.visibleipv4 address for those + * cases). */ {CONF_VAR_INT, "udpport", {.num = 0}}, + /** Specifies a specific TCP port to use for DC peer + * connections. If left unspecified, a port is allocated + * dynamically. Useful for NAT routers (see also the + * net.visibleipv4 address for those cases). */ {CONF_VAR_INT, "tcpport", {.num = 0}}, + /** If set to true, doldacond will do its best to emulate DC++ + * (currently v0.674). This should be left off if at all possible, + * since turning it on will violate the rules of most hubs and + * thus give hub owners an actual reason to kick you if it is + * detected. It might be needed for some of the more bone-headed + * hub owners, though. Note that DC++ emulation can also be turned + * on or off for individual hubs, overriding this setting. */ {CONF_VAR_BOOL, "dcppemu", {.num = 0}}, {CONF_VAR_END} };