Revert to previous socket scheme.
[doldaconnect.git] / daemon / fnet-dc.c
index 804bd2c..d45b144 100644 (file)
@@ -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");