diff options
Diffstat (limited to 'net/openbgpd/files/patch-bgpd_buffer.c')
-rw-r--r-- | net/openbgpd/files/patch-bgpd_buffer.c | 358 |
1 files changed, 283 insertions, 75 deletions
diff --git a/net/openbgpd/files/patch-bgpd_buffer.c b/net/openbgpd/files/patch-bgpd_buffer.c index 875b789f68b3..7ca7a41c1438 100644 --- a/net/openbgpd/files/patch-bgpd_buffer.c +++ b/net/openbgpd/files/patch-bgpd_buffer.c @@ -1,39 +1,182 @@ Index: bgpd/buffer.c =================================================================== -RCS file: /home/cvs/private/hrs/openbgpd/bgpd/buffer.c,v -retrieving revision 1.1.1.7 -retrieving revision 1.1.1.8 -diff -u -p -r1.1.1.7 -r1.1.1.8 +RCS file: bgpd/buffer.c +diff -N bgpd/buffer.c --- bgpd/buffer.c 14 Feb 2010 20:19:57 -0000 1.1.1.7 -+++ bgpd/buffer.c 14 Feb 2010 20:27:06 -0000 1.1.1.8 -@@ -1,4 +1,4 @@ ++++ /dev/null 1 Jan 1970 00:00:00 -0000 +@@ -1,305 +0,0 @@ -/* $OpenBSD: buffer.c,v 1.43 2009/06/06 06:33:15 eric Exp $ */ -+/* $OpenBSD: buffer.c,v 1.44 2009/07/23 18:58:42 eric Exp $ */ - - /* - * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> -@@ -144,7 +144,7 @@ int - buf_write(struct msgbuf *msgbuf) - { - struct iovec iov[IOV_MAX]; +- +-/* +- * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> +- * +- * Permission to use, copy, modify, and distribute this software for any +- * purpose with or without fee is hereby granted, provided that the above +- * copyright notice and this permission notice appear in all copies. +- * +- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +- */ +- +-#include <sys/param.h> +-#include <sys/queue.h> +-#include <sys/socket.h> +-#include <sys/uio.h> +- +-#include <errno.h> +-#include <stdlib.h> +-#include <string.h> +-#include <unistd.h> +- +-#include "imsg.h" +- +-int buf_realloc(struct buf *, size_t); +-void buf_enqueue(struct msgbuf *, struct buf *); +-void buf_dequeue(struct msgbuf *, struct buf *); +- +-struct buf * +-buf_open(size_t len) +-{ +- struct buf *buf; +- +- if ((buf = calloc(1, sizeof(struct buf))) == NULL) +- return (NULL); +- if ((buf->buf = malloc(len)) == NULL) { +- free(buf); +- return (NULL); +- } +- buf->size = buf->max = len; +- buf->fd = -1; +- +- return (buf); +-} +- +-struct buf * +-buf_dynamic(size_t len, size_t max) +-{ +- struct buf *buf; +- +- if (max < len) +- return (NULL); +- +- if ((buf = buf_open(len)) == NULL) +- return (NULL); +- +- 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) +- if (buf_realloc(buf, len) == -1) +- return (-1); +- +- memcpy(buf->buf + buf->wpos, data, len); +- buf->wpos += len; +- return (0); +-} +- +-void * +-buf_reserve(struct buf *buf, size_t len) +-{ +- void *b; +- +- if (buf->wpos + len > buf->size) +- 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); +-} +- +-void +-buf_close(struct msgbuf *msgbuf, struct buf *buf) +-{ +- buf_enqueue(msgbuf, buf); +-} +- +-int +-buf_write(struct msgbuf *msgbuf) +-{ +- struct iovec iov[IOV_MAX]; - struct buf *buf, *next; -+ struct buf *buf; - unsigned int i = 0; - ssize_t n; - -@@ -153,7 +153,7 @@ buf_write(struct msgbuf *msgbuf) - if (i >= IOV_MAX) - break; - iov[i].iov_base = buf->buf + buf->rpos; +- unsigned int i = 0; +- ssize_t n; +- +- bzero(&iov, sizeof(iov)); +- TAILQ_FOREACH(buf, &msgbuf->bufs, entry) { +- if (i >= IOV_MAX) +- break; +- iov[i].iov_base = buf->buf + buf->rpos; - iov[i].iov_len = buf->size - buf->rpos; -+ iov[i].iov_len = buf->wpos - buf->rpos; - i++; - } - -@@ -170,17 +170,7 @@ buf_write(struct msgbuf *msgbuf) - return (-2); - } - +- i++; +- } +- +- if ((n = writev(msgbuf->fd, iov, i)) == -1) { +- if (errno == EAGAIN || errno == ENOBUFS || +- errno == EINTR) /* try later */ +- return (0); +- else +- return (-1); +- } +- +- if (n == 0) { /* connection closed */ +- errno = 0; +- return (-2); +- } +- - for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; - buf = next) { - next = TAILQ_NEXT(buf, entry); @@ -45,48 +188,95 @@ diff -u -p -r1.1.1.7 -r1.1.1.8 - n = 0; - } - } -+ msgbuf_drain(msgbuf, n); - - return (0); - } -@@ -201,6 +191,24 @@ msgbuf_init(struct msgbuf *msgbuf) - } - - void -+msgbuf_drain(struct msgbuf *msgbuf, size_t n) -+{ -+ struct buf *buf, *next; -+ -+ for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; -+ buf = next) { -+ next = TAILQ_NEXT(buf, entry); -+ if (buf->rpos + n >= buf->wpos) { -+ n -= buf->wpos - buf->rpos; -+ buf_dequeue(msgbuf, buf); -+ } else { -+ buf->rpos += n; -+ n = 0; -+ } -+ } -+} -+ -+void - msgbuf_clear(struct msgbuf *msgbuf) - { - struct buf *buf; -@@ -213,7 +221,7 @@ int - msgbuf_write(struct msgbuf *msgbuf) - { - struct iovec iov[IOV_MAX]; +- +- return (0); +-} +- +-void +-buf_free(struct buf *buf) +-{ +- free(buf->buf); +- free(buf); +-} +- +-void +-msgbuf_init(struct msgbuf *msgbuf) +-{ +- msgbuf->queued = 0; +- msgbuf->fd = -1; +- TAILQ_INIT(&msgbuf->bufs); +-} +- +-void +-msgbuf_clear(struct msgbuf *msgbuf) +-{ +- struct buf *buf; +- +- while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL) +- buf_dequeue(msgbuf, buf); +-} +- +-int +-msgbuf_write(struct msgbuf *msgbuf) +-{ +- struct iovec iov[IOV_MAX]; - struct buf *buf, *next; -+ struct buf *buf; - unsigned int i = 0; - ssize_t n; - struct msghdr msg; -@@ -270,17 +278,7 @@ msgbuf_write(struct msgbuf *msgbuf) - buf->fd = -1; - } - +- unsigned int i = 0; +- ssize_t n; +- struct msghdr msg; +- struct cmsghdr *cmsg; +- union { +- struct cmsghdr hdr; +- char buf[CMSG_SPACE(sizeof(int))]; +- } cmsgbuf; +- +- bzero(&iov, sizeof(iov)); +- bzero(&msg, sizeof(msg)); +- TAILQ_FOREACH(buf, &msgbuf->bufs, entry) { +- if (i >= IOV_MAX) +- break; +- iov[i].iov_base = buf->buf + buf->rpos; +- iov[i].iov_len = buf->wpos - buf->rpos; +- i++; +- if (buf->fd != -1) +- break; +- } +- +- msg.msg_iov = iov; +- msg.msg_iovlen = i; +- +- if (buf != NULL && buf->fd != -1) { +- msg.msg_control = (caddr_t)&cmsgbuf.buf; +- msg.msg_controllen = sizeof(cmsgbuf.buf); +- cmsg = CMSG_FIRSTHDR(&msg); +- cmsg->cmsg_len = CMSG_LEN(sizeof(int)); +- cmsg->cmsg_level = SOL_SOCKET; +- cmsg->cmsg_type = SCM_RIGHTS; +- *(int *)CMSG_DATA(cmsg) = buf->fd; +- } +- +- if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) { +- if (errno == EAGAIN || errno == ENOBUFS || +- errno == EINTR) /* try later */ +- return (0); +- else +- return (-1); +- } +- +- if (n == 0) { /* connection closed */ +- errno = 0; +- return (-2); +- } +- +- /* +- * assumption: fd got sent if sendmsg sent anything +- * this works because fds are passed one at a time +- */ +- if (buf != NULL && buf->fd != -1) { +- close(buf->fd); +- buf->fd = -1; +- } +- - for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; - buf = next) { - next = TAILQ_NEXT(buf, entry); @@ -98,7 +288,25 @@ diff -u -p -r1.1.1.7 -r1.1.1.8 - n = 0; - } - } -+ msgbuf_drain(msgbuf, n); - - return (0); - } +- +- return (0); +-} +- +-void +-buf_enqueue(struct msgbuf *msgbuf, struct buf *buf) +-{ +- TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry); +- msgbuf->queued++; +-} +- +-void +-buf_dequeue(struct msgbuf *msgbuf, struct buf *buf) +-{ +- TAILQ_REMOVE(&msgbuf->bufs, buf, entry); +- +- if (buf->fd != -1) +- close(buf->fd); +- +- msgbuf->queued--; +- buf_free(buf); +-} |