Merge branch 'socket' into transsock
[doldaconnect.git] / daemon / fnet-dc.c
index 828e6d0..348a53a 100644 (file)
@@ -122,6 +122,7 @@ struct dcpeer
     struct timer *timeout;
     struct qcmdqueue queue;
     struct transfer *transfer;
+    struct socket *trpipe;
     int state;
     int ptclose;      /* Close after transfer is complete */
     int accepted;     /* If false, we connected, otherwise, we accepted */
@@ -139,7 +140,6 @@ struct dcpeer
 };
 
 static struct fnet dcnet;
-static struct transferiface dctransfer;
 static struct socket *udpsock = NULL;
 static struct lport *tcpsock = NULL;
 static struct dcpeer *peers = NULL;
@@ -150,6 +150,7 @@ static char *xmllistname = NULL;
 static char *xmlbz2listname = NULL;
 static struct timer *listwritetimer = NULL;
 
+static struct socket *mktrpipe(struct dcpeer *peer);
 static void peerconnect(struct socket *sk, int err, struct fnetnode *fn);
 static void freedcpeer(struct dcpeer *peer);
 static void transread(struct socket *sk, struct dcpeer *peer);
@@ -1322,7 +1323,6 @@ static void cmd_connecttome(struct socket *sk, struct fnetnode *fn, char *cmd, c
 {
     char *p;
     struct dchub *hub;
-    struct socket *newsk;
     struct sockaddr_in addr;
     
     hub = fn->data;
@@ -1339,7 +1339,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), (void (*)(struct socket *, int, void *))peerconnect, fn);
+    putsock(netcsconn((struct sockaddr *)&addr, sizeof(addr), (void (*)(struct socket *, int, void *))peerconnect, fn));
     getfnetnode(fn);
     hubhandleaction(sk, fn, cmd, args);
 }
@@ -1622,14 +1622,14 @@ static void cmd_direction(struct socket *sk, struct dcpeer *peer, char *cmd, cha
                peer->close = 1;
                return;
            }
-           transfer = newupload(peer->fn, &dcnet, peer->wcsname, &dctransfer, peer);
+           transfer = newupload(peer->fn, &dcnet, peer->wcsname, (peer->trpipe = mktrpipe(peer))->back);
        } else {
            if((transfer = finddownload(peer->wcsname)) == NULL)
            {
                peer->close = 1;
                return;
            }
-           transferattach(transfer, &dctransfer, peer);
+           transferattach(transfer, (peer->trpipe = mktrpipe(peer))->back);
            transfersetstate(transfer, TRNS_HS);
        }
        transfersetnick(transfer, peer->wcsname);
@@ -1674,10 +1674,10 @@ static void cmd_peerlock(struct socket *sk, struct dcpeer *peer, char *cmd, char
                return;
            }
            peer->direction = TRNSD_UP;
-           transfer = newupload(peer->fn, &dcnet, peer->wcsname, &dctransfer, peer);
+           transfer = newupload(peer->fn, &dcnet, peer->wcsname, (peer->trpipe = mktrpipe(peer))->back);
        } else {
            peer->direction = TRNSD_DOWN;
-           transferattach(transfer, &dctransfer, peer);
+           transferattach(transfer, (peer->trpipe = mktrpipe(peer))->back);
            transfersetstate(transfer, TRNS_HS);
        }
        transfersetnick(transfer, peer->wcsname);
@@ -1714,6 +1714,7 @@ static void startul(struct dcpeer *peer)
     peer->state = PEER_TRNS;
     transferstartul(peer->transfer, peer->sk);
     peer->sk->writecb = (void (*)(struct socket *, void *))transwrite;
+    transwrite(peer->sk, peer);
 }
 
 static void cmd_filelength(struct socket *sk, struct dcpeer *peer, char *cmd, char *args)
@@ -2675,13 +2676,6 @@ static struct command peercmds[] =
 };
 #undef cc
 
-static void dctransdetach(struct transfer *transfer, struct dcpeer *peer)
-{
-    CBUNREG(transfer, trans_filterout, peer);
-    peer->transfer = NULL;
-    peer->close = 1;
-}
-
 static void dctransgotdata(struct transfer *transfer, struct dcpeer *peer)
 {
     int ret;
@@ -2694,7 +2688,7 @@ static void dctransgotdata(struct transfer *transfer, struct dcpeer *peer)
     {
        if(sockqueueleft(peer->sk) > 0)
        {
-           if((buf = transfergetdata(transfer, &bufsize)) != NULL)
+           if((buf = sockgetinbuf(peer->trpipe, &bufsize)) != NULL)
            {
                if(peer->compress == CPRS_NONE)
                {
@@ -2757,45 +2751,35 @@ static void dctransgotdata(struct transfer *transfer, struct dcpeer *peer)
     }
 }
 
-static void dctransendofdata(struct transfer *transfer, struct dcpeer *peer)
-{
-    peer->state = PEER_SYNC;
-    dctransgotdata(transfer, peer);
-}
-
 static void transread(struct socket *sk, struct dcpeer *peer)
 {
     void *buf;
     size_t bufsize;
-    struct transfer *transfer;
     
-    if(transferdatasize(peer->transfer) < 0)
+    if(sockqueueleft(peer->trpipe) < 0)
        return;
-    if((buf = sockgetinbuf(sk, &bufsize)) == NULL)
-       return;
-    if(peer->transfer == NULL)
+    if((buf = sockgetinbuf(sk, &bufsize)) != NULL)
     {
+       if(peer->transfer == NULL)
+       {
+           free(buf);
+           freedcpeer(peer);
+           return;
+       }
+       sockqueue(peer->trpipe, buf, bufsize);
        free(buf);
-       freedcpeer(peer);
-       return;
     }
-    transferputdata(peer->transfer, buf, bufsize);
-    free(buf);
     if(peer->transfer->curpos >= peer->transfer->size)
     {
-       transfer = peer->transfer;
-       transferdetach(transfer);
-       transferendofdata(transfer);
+       closesock(peer->trpipe);
+       quitsock(peer->trpipe);
+       peer->trpipe = NULL;
+       peer->transfer = NULL;
+       peer->close = 1;
        return;
     }
 }
 
-static void dcwantdata(struct transfer *transfer, struct dcpeer *peer)
-{
-    if(transferdatasize(transfer) > 0)
-       transread(peer->sk, peer);
-}
-
 static void transerr(struct socket *sk, int err, struct dcpeer *peer)
 {
     struct transfer *transfer;
@@ -2805,8 +2789,11 @@ static void transerr(struct socket *sk, int err, struct dcpeer *peer)
        freedcpeer(peer);
        return;
     }
-    transferdetach(transfer);
-    transferendofdata(transfer);
+    closesock(peer->trpipe);
+    quitsock(peer->trpipe);
+    peer->trpipe = NULL;
+    peer->transfer = NULL;
+    peer->close = 1;
 }
 
 static void transwrite(struct socket *sk, struct dcpeer *peer)
@@ -2821,6 +2808,35 @@ static void transwrite(struct socket *sk, struct dcpeer *peer)
     dctransgotdata(peer->transfer, peer);
 }
 
+static void trpiperead(struct socket *sk, struct dcpeer *peer)
+{
+    dctransgotdata(peer->transfer, peer);
+}
+
+static void trpipewrite(struct socket *sk, struct dcpeer *peer)
+{
+    transread(peer->sk, peer);
+}
+
+static void trpipeerr(struct socket *sk, int errno, struct dcpeer *peer)
+{
+    peer->state = PEER_SYNC;
+    dctransgotdata(peer->transfer, peer);
+    CBUNREG(peer->transfer, trans_filterout, peer);
+}
+
+static struct socket *mktrpipe(struct dcpeer *peer)
+{
+    struct socket *sk;
+    
+    sk = netsockpipe();
+    sk->data = peer;
+    sk->readcb = (void (*)(struct socket *, void *))trpiperead;
+    sk->writecb = (void (*)(struct socket *, void *))trpipewrite;
+    sk->errcb = (void (*)(struct socket *, int, void *))trpipeerr;
+    return(sk);
+}
+
 static void udpread(struct socket *sk, void *data)
 {
     char *buf, *p, *p2, *hashbuf;
@@ -3122,8 +3138,13 @@ static void freedcpeer(struct dcpeer *peer)
        peer->next->prev = peer->prev;
     if(peer->prev != NULL)
        peer->prev->next = peer->next;
+    if(peer->trpipe != NULL) {
+       closesock(peer->trpipe);
+       quitsock(peer->trpipe);
+    }
     if(peer->transfer != NULL)
     {
+       CBUNREG(peer->transfer, trans_filterout, peer);
        if(peer->transfer->dir == TRNSD_UP)
            peer->transfer->close = 1;
        if(peer->transfer->dir == TRNSD_DOWN)
@@ -3209,14 +3230,6 @@ static void hubkill(struct fnetnode *fn)
     closesock(hub->sk);
 }
 
-static struct transferiface dctransfer =
-{
-    .detach = (void (*)(struct transfer *, void *))dctransdetach,
-    .gotdata = (void (*)(struct transfer *, void *))dctransgotdata,
-    .endofdata = (void (*)(struct transfer *, void *))dctransendofdata,
-    .wantdata = (void (*)(struct transfer *, void *))dcwantdata
-};
-
 static struct fnet dcnet =
 {
     .name = L"dc",
@@ -3238,6 +3251,9 @@ static void peerread(struct socket *sk, struct dcpeer *peer)
     if(peer->state == PEER_CMD) {
        if((peer->queue.size > 50) || (peer->inbufdata > 65536))
            return;
+    } else if(peer->state == PEER_TTHL) {
+    } else {
+       return;
     }
     if((newbuf = sockgetinbuf(sk, &datalen)) == NULL)
        return;
@@ -3284,7 +3300,6 @@ static void peerconnect(struct socket *sk, int err, struct fnetnode *fn)
     if(err != 0)
     {
        putfnetnode(fn);
-       putsock(sk);
        return;
     }
     hub = fn->data;
@@ -3296,7 +3311,6 @@ static void peerconnect(struct socket *sk, int err, struct fnetnode *fn)
     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);