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 */
};
static struct fnet dcnet;
-static struct transferiface dctransfer;
static struct socket *udpsock = NULL;
static struct lport *tcpsock = NULL;
static struct dcpeer *peers = 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);
peer->close = 1;
return;
}
- transfer = newupload(peer->fn, &dcnet, peer->wcsname, &dctransfer, peer);
+ transfer = newupload(peer->fn, &dcnet, peer->wcsname, peer->trpipe = mktrpipe(peer));
} else {
if((transfer = finddownload(peer->wcsname)) == NULL)
{
peer->close = 1;
return;
}
- transferattach(transfer, &dctransfer, peer);
+ transferattach(transfer, peer->trpipe = mktrpipe(peer));
transfersetstate(transfer, TRNS_HS);
}
transfersetnick(transfer, peer->wcsname);
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));
} else {
peer->direction = TRNSD_DOWN;
- transferattach(transfer, &dctransfer, peer);
+ transferattach(transfer, peer->trpipe = mktrpipe(peer));
transfersetstate(transfer, TRNS_HS);
}
transfersetnick(transfer, peer->wcsname);
};
#undef cc
+static struct socket *mktrpipe(struct dcpeer *peer)
+{
+ struct socket *sk;
+
+ sk = netsockpipe();
+ sk->data = peer;
+ return(sk);
+}
+
static void dctransdetach(struct transfer *transfer, struct dcpeer *peer)
{
CBUNREG(transfer, trans_filterout, peer);
if((peer->state == PEER_TRNS) || (peer->state == PEER_SYNC))
{
- if(sockqueuesize(peer->sk) < 65536)
+ if(sockqueueleft(peer->sk) > 0)
{
if((buf = transfergetdata(transfer, &bufsize)) != NULL)
{
dctransgotdata(transfer, peer);
}
-static void dcwantdata(struct transfer *transfer, struct dcpeer *peer)
-{
- if(transferdatasize(transfer) < 65536)
- sockblock(peer->sk, 0);
-}
-
static void transread(struct socket *sk, struct dcpeer *peer)
{
void *buf;
size_t bufsize;
struct transfer *transfer;
+ if(transferdatasize(peer->transfer) < 0)
+ return;
if((buf = sockgetinbuf(sk, &bufsize)) == NULL)
return;
if(peer->transfer == NULL)
transferendofdata(transfer);
return;
}
- if(transferdatasize(peer->transfer) > 65535)
- sockblock(sk, 1);
+}
+
+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)
char *p, *p2;
hub = (struct dchub *)fn->data;
+ if(hub->queue.size > 1000)
+ return;
if((newbuf = sockgetinbuf(sk, &datalen)) == NULL)
return;
if(hub->inbufdata > 500000) /* Discard possible malicious data */
p = p2;
}
memmove(hub->inbuf, p, hub->inbufdata -= p - hub->inbuf);
- if(hub->queue.size > 1000)
- sockblock(sk, 1);
}
static void huberr(struct socket *sk, int err, struct fnetnode *fn)
peer->next->prev = peer->prev;
if(peer->prev != NULL)
peer->prev->next = peer->next;
+ if(peer->trpipe != NULL) {
+ closesock(peer->trpipe);
+ putsock(peer->trpipe);
+ }
if(peer->transfer != NULL)
{
if(peer->transfer->dir == TRNSD_UP)
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",
size_t datalen, cnlen;
struct command *cmd;
+ if(peer->state == PEER_CMD) {
+ if((peer->queue.size > 50) || (peer->inbufdata > 65536))
+ return;
+ }
if((newbuf = sockgetinbuf(sk, &datalen)) == NULL)
return;
sizebuf2(peer->inbuf, peer->inbufdata + datalen, 1);
{
peer->state = PEER_STOP;
break;
- } else {
- if(peer->queue.size > 50)
- sockblock(sk, 1);
}
}
} else if(peer->state == PEER_TTHL) {
handletthl(peer);
}
- if(peer->inbufdata > 500000)
- sockblock(sk, 1);
}
static void peererror(struct socket *sk, int err, struct dcpeer *peer)
if(err != 0)
{
putfnetnode(fn);
- putsock(sk);
return;
}
hub = fn->data;
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);
quota--;
}
if(hub->queue.size < 1000)
- sockblock(hub->sk, 0);
+ hubread(hub->sk, fn);
if(quota < 1)
break;
}
quota--;
}
if((peer->queue.size < 50) && (peer->inbufdata < 500000))
- sockblock(peer->sk, 0);
+ peerread(peer->sk, peer);
if(quota < 1)
break;
}