Dolda2000 GitWeb
/
doldaconnect.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
821e384
)
Made the DC protocol readers a bit more resilient to faulty peers.
author
Fredrik Tolf
<fredrik@dolda2000.com>
Sun, 24 Feb 2008 05:39:20 +0000
(06:39 +0100)
committer
Fredrik Tolf
<fredrik@dolda2000.com>
Sun, 24 Feb 2008 05:39:20 +0000
(06:39 +0100)
daemon/fnet-dc.c
patch
|
blob
|
blame
|
history
diff --git
a/daemon/fnet-dc.c
b/daemon/fnet-dc.c
index
87671aa
..
dc26782
100644
(file)
--- a/
daemon/fnet-dc.c
+++ b/
daemon/fnet-dc.c
@@
-91,6
+91,7
@@
struct command
char *name;
void (*handler)(struct socket *sk, void *data, char *cmd, char *args);
int stop;
char *name;
void (*handler)(struct socket *sk, void *data, char *cmd, char *args);
int stop;
+ int limit;
};
struct qcommand
};
struct qcommand
@@
-102,6
+103,7
@@
struct qcommand
struct qcmdqueue
{
struct qcommand *f, *l;
struct qcmdqueue
{
struct qcommand *f, *l;
+ int size;
};
struct dchub
};
struct dchub
@@
-393,6
+395,7
@@
static struct qcommand *newqcmd(struct qcmdqueue *queue, char *string)
else
queue->l->next = new;
queue->l = new;
else
queue->l->next = new;
queue->l = new;
+ queue->size++;
return(new);
}
return(new);
}
@@
-404,6
+407,7
@@
static struct qcommand *ulqcmd(struct qcmdqueue *queue)
return(NULL);
if((queue->f = qcmd->next) == NULL)
queue->l = NULL;
return(NULL);
if((queue->f = qcmd->next) == NULL)
queue->l = NULL;
+ queue->size--;
return(qcmd);
}
return(qcmd);
}
@@
-2628,10
+2632,10
@@
static struct command hubcmds[] =
{"$OpList", cc(cmd_oplist)},
{"$MyINFO", cc(cmd_myinfo)},
{"$ForceMove", cc(cmd_forcemove)},
{"$OpList", cc(cmd_oplist)},
{"$MyINFO", cc(cmd_myinfo)},
{"$ForceMove", cc(cmd_forcemove)},
- {"$Search", cc(cmd_search)},
- {"$MultiSearch", cc(cmd_search)},
- {"$ConnectToMe", cc(cmd_connecttome)},
- {"$RevConnectToMe", cc(cmd_revconnecttome)},
+ {"$Search", cc(cmd_search)
, .limit = 100
},
+ {"$MultiSearch", cc(cmd_search)
, .limit = 50
},
+ {"$ConnectToMe", cc(cmd_connecttome)
, .limit = 200
},
+ {"$RevConnectToMe", cc(cmd_revconnecttome)
, .limit = 500
},
{"$GetNetInfo", cc(cmd_getnetinfo)},
{"$To:", cc(cmd_to)},
{"$SR", cc(cmd_sr)},
{"$GetNetInfo", cc(cmd_getnetinfo)},
{"$To:", cc(cmd_to)},
{"$SR", cc(cmd_sr)},
@@
-2659,8
+2663,8
@@
static struct command peercmds[] =
{"$GetZBlock", cc(cmd_getblock)},
{"$UGetZBlock", cc(cmd_getblock)},
{"$ADCGET", cc(cmd_adcget)},
{"$GetZBlock", cc(cmd_getblock)},
{"$UGetZBlock", cc(cmd_getblock)},
{"$ADCGET", cc(cmd_adcget)},
- {"$ADCSND", cc(cmd_adcsnd), 1},
- {"$Sending", cc(cmd_sending), 1},
+ {"$ADCSND", cc(cmd_adcsnd),
.stop =
1},
+ {"$Sending", cc(cmd_sending),
.stop =
1},
{NULL, NULL}
};
#undef cc
{NULL, NULL}
};
#undef cc
@@
-2977,8
+2981,9
@@
static void udpread(struct socket *sk, void *data)
static void hubread(struct socket *sk, struct fnetnode *fn)
{
struct dchub *hub;
static void hubread(struct socket *sk, struct fnetnode *fn)
{
struct dchub *hub;
+ struct command *cmd;
char *newbuf;
char *newbuf;
- size_t datalen;
+ size_t datalen
, cnlen
;
char *p;
hub = (struct dchub *)fn->data;
char *p;
hub = (struct dchub *)fn->data;
@@
-2994,11
+2999,22
@@
static void hubread(struct socket *sk, struct fnetnode *fn)
while((datalen > 0) && ((p = memchr(p, '|', datalen)) != NULL))
{
*(p++) = 0;
while((datalen > 0) && ((p = memchr(p, '|', datalen)) != NULL))
{
*(p++) = 0;
- newqcmd(&hub->queue, hub->inbuf);
+ for(cmd = hubcmds; cmd->handler != NULL; cmd++)
+ {
+ cnlen = strlen(cmd->name);
+ if(!strncmp(hub->inbuf, cmd->name, cnlen) && ((hub->inbuf[cnlen] == ' ') || (hub->inbuf[cnlen] == 0)))
+ break;
+ }
+ if((cmd->limit == 0) || (hub->queue.size < cmd->limit))
+ newqcmd(&hub->queue, hub->inbuf);
memmove(hub->inbuf, p, hub->inbufdata -= p - hub->inbuf);
datalen = hub->inbufdata;
p = hub->inbuf;
}
memmove(hub->inbuf, p, hub->inbufdata -= p - hub->inbuf);
datalen = hub->inbufdata;
p = hub->inbuf;
}
+ if(hub->queue.size > 1000)
+ sk->ignread = 1;
+ else
+ sk->ignread = 0;
}
static void huberr(struct socket *sk, int err, struct fnetnode *fn)
}
static void huberr(struct socket *sk, int err, struct fnetnode *fn)
@@
-3224,11
+3240,13
@@
static struct fnet dcnet =
static void peerread(struct socket *sk, struct dcpeer *peer)
{
char *newbuf, *p;
static void peerread(struct socket *sk, struct dcpeer *peer)
{
char *newbuf, *p;
- size_t datalen;
+ size_t datalen
, cnlen
;
struct command *cmd;
if((newbuf = sockgetinbuf(sk, &datalen)) == NULL)
return;
struct command *cmd;
if((newbuf = sockgetinbuf(sk, &datalen)) == NULL)
return;
+ if(peer->inbufdata > 500000) /* Discard possibly malicious data */
+ peer->inbufdata = 0;
sizebuf2(peer->inbuf, peer->inbufdata + datalen, 1);
memcpy(peer->inbuf + peer->inbufdata, newbuf, datalen);
free(newbuf);
sizebuf2(peer->inbuf, peer->inbufdata + datalen, 1);
memcpy(peer->inbuf + peer->inbufdata, newbuf, datalen);
free(newbuf);
@@
-3239,17
+3257,24
@@
static void peerread(struct socket *sk, struct dcpeer *peer)
while((peer->inbufdata > 0) && (p = memchr(peer->inbuf, '|', peer->inbufdata)) != NULL)
{
*(p++) = 0;
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++)
{
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)] == '|')))
+ cnlen = strlen(cmd->name);
+ if(!strncmp(peer->inbuf, cmd->name, cnlen) && ((peer->inbuf[cnlen] == ' ') || (peer->inbuf[cnlen] == 0)))
break;
}
break;
}
+ if((cmd->limit == 0) || (peer->queue.size < cmd->limit))
+ newqcmd(&peer->queue, peer->inbuf);
memmove(peer->inbuf, p, peer->inbufdata -= p - peer->inbuf);
if(cmd->stop)
{
peer->state = PEER_STOP;
break;
memmove(peer->inbuf, p, peer->inbufdata -= p - peer->inbuf);
if(cmd->stop)
{
peer->state = PEER_STOP;
break;
+ } else {
+ if(peer->queue.size > 1000)
+ sk->ignread = 1;
+ else
+ sk->ignread = 0;
}
}
} else if(peer->state == PEER_TTHL) {
}
}
} else if(peer->state == PEER_TTHL) {