diff options
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 8 | ||||
-rw-r--r-- | usr.sbin/bgpd/buffer.c | 72 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.c | 6 |
3 files changed, 67 insertions, 19 deletions
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index fe7b77287b4..5764610296c 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.223 2008/12/12 23:15:12 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.224 2009/03/13 04:40:55 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -109,6 +109,7 @@ struct buf { TAILQ_ENTRY(buf) entry; u_char *buf; size_t size; + size_t max; size_t wpos; size_t rpos; int fd; @@ -734,9 +735,12 @@ int bgpd_filternexthop(struct kroute *, struct kroute6 *); /* buffer.c */ struct buf *buf_open(size_t); -struct buf *buf_grow(struct buf *, size_t); +struct buf *buf_dynamic(size_t, size_t); int buf_add(struct buf *, const void *, size_t); void *buf_reserve(struct buf *, size_t); +void *buf_seek(struct buf *, size_t, size_t); +size_t buf_size(struct buf *); +size_t buf_left(struct buf *); int buf_close(struct msgbuf *, struct buf *); int buf_write(int, struct buf *); void buf_free(struct buf *); diff --git a/usr.sbin/bgpd/buffer.c b/usr.sbin/bgpd/buffer.c index 36574934d8e..bb4ac46d53f 100644 --- a/usr.sbin/bgpd/buffer.c +++ b/usr.sbin/bgpd/buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.c,v 1.40 2008/10/03 15:20:29 eric Exp $ */ +/* $OpenBSD: buffer.c,v 1.41 2009/03/13 04:40:55 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -28,6 +28,7 @@ #include "bgpd.h" +int buf_realloc(struct buf *, size_t); void buf_enqueue(struct msgbuf *, struct buf *); void buf_dequeue(struct msgbuf *, struct buf *); @@ -42,35 +43,55 @@ buf_open(size_t len) free(buf); return (NULL); } - buf->size = len; + buf->size = buf->max = len; buf->fd = -1; return (buf); } struct buf * -buf_grow(struct buf *buf, size_t len) +buf_dynamic(size_t len, size_t max) { - void *p; + struct buf *buf; - if ((p = realloc(buf->buf, buf->size + len)) == NULL) { - free(buf->buf); - buf->buf = NULL; - buf->size = 0; + if (max < len) + return (NULL); + + if ((buf = buf_open(len)) == NULL) return (NULL); - } - buf->buf = p; - buf->size += len; + if (max > 0) + buf->max = max; return (buf); } int +buf_realloc(struct buf *buf, size_t len) +{ + u_char *b; + + /* on static buffers max is eq size and so the following fails */ + if (buf->wpos + len > buf->max) { + errno = ENOMEM; + return (-1); + } + + b = realloc(buf->buf, buf->wpos + len); + if (b == NULL) + return (-1); + buf->buf = b; + buf->size = buf->wpos + len; + + return (0); +} + +int buf_add(struct buf *buf, const void *data, size_t len) { if (buf->wpos + len > buf->size) - return (-1); + if (buf_realloc(buf, len) == -1) + return (-1); memcpy(buf->buf + buf->wpos, data, len); buf->wpos += len; @@ -83,16 +104,41 @@ buf_reserve(struct buf *buf, size_t len) void *b; if (buf->wpos + len > buf->size) - return (NULL); + if (buf_realloc(buf, len) == -1) + return (NULL); b = buf->buf + buf->wpos; buf->wpos += len; return (b); } +void * +buf_seek(struct buf *buf, size_t pos, size_t len) +{ + /* only allowed to seek in already written parts */ + if (pos + len > buf->wpos) + return (NULL); + + return (buf->buf + pos); +} + +size_t +buf_size(struct buf *buf) +{ + return (buf->wpos); +} + +size_t +buf_left(struct buf *buf) +{ + return (buf->max - buf->wpos); +} + int buf_close(struct msgbuf *msgbuf, struct buf *buf) { + /* truncate buffer to the correct length before queuing */ + buf->size = buf->wpos; buf_enqueue(msgbuf, buf); return (1); } diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index b763e35814e..f3a4d9b8e55 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.284 2008/09/11 14:49:58 henning Exp $ */ +/* $OpenBSD: session.c,v 1.285 2009/03/13 04:40:55 claudio Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org> @@ -1253,8 +1253,6 @@ session_capa_add(struct peer *p, struct buf *opb, u_int8_t capa_code, op_type = OPT_PARAM_CAPABILITIES; op_len = sizeof(capa_code) + sizeof(capa_len) + capa_len; tot_len = sizeof(op_type) + sizeof(op_len) + op_len; - if (buf_grow(opb, tot_len) == NULL) - return (1); errs += buf_add(opb, &op_type, sizeof(op_type)); errs += buf_add(opb, &op_len, sizeof(op_len)); errs += buf_add(opb, &capa_code, sizeof(capa_code)); @@ -1346,7 +1344,7 @@ session_open(struct peer *p) u_int errs = 0; - if ((opb = buf_open(0)) == NULL) { + if ((opb = buf_dynamic(0, MAX_PKTSIZE - MSGSIZE_OPEN_MIN)) == NULL) { bgp_fsm(p, EVNT_CON_FATAL); return; } |