#include "poll-loop.h"
#include "socket-util.h"
#include "vconn.h"
+#include "vconn-provider.h"
#include "vlog.h"
#define THIS_MODULE VLM_vconn_stream
static struct vconn_class stream_vconn_class;
+static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(10, 25);
+
int
new_stream_vconn(const char *name, int fd, int connect_status,
uint32_t ip, struct vconn **vconnp)
struct stream_vconn *s;
s = xmalloc(sizeof *s);
- s->vconn.class = &stream_vconn_class;
- s->vconn.connect_status = connect_status;
- s->vconn.ip = ip;
+ vconn_init(&s->vconn, &stream_vconn_class, connect_status, ip, name);
s->fd = fd;
s->txbuf = NULL;
s->tx_waiter = NULL;
static struct stream_vconn *
stream_vconn_cast(struct vconn *vconn)
{
- assert(vconn->class == &stream_vconn_class);
+ vconn_assert_class(vconn, &stream_vconn_class);
return CONTAINER_OF(vconn, struct stream_vconn, vconn);
}
struct ofp_header *oh = rx->data;
size_t length = ntohs(oh->length);
if (length < sizeof(struct ofp_header)) {
- VLOG_ERR("received too-short ofp_header (%zu bytes)", length);
+ VLOG_ERR_RL(&rl, "received too-short ofp_header (%zu bytes)",
+ length);
return EPROTO;
}
want_bytes = length - rx->size;
return EAGAIN;
} else if (retval == 0) {
if (rx->size) {
- VLOG_ERR("connection dropped mid-packet");
+ VLOG_ERR_RL(&rl, "connection dropped mid-packet");
return EPROTO;
} else {
return EOF;
ssize_t n = write(s->fd, s->txbuf->data, s->txbuf->size);
if (n < 0) {
if (errno != EAGAIN) {
- VLOG_ERR("send: %s", strerror(errno));
+ VLOG_ERR_RL(&rl, "send: %s", strerror(errno));
stream_clear_txbuf(s);
return;
}
\f
/* Passive stream socket vconn. */
-struct pstream_vconn
+struct pstream_pvconn
{
- struct vconn vconn;
+ struct pvconn pvconn;
int fd;
int (*accept_cb)(int fd, const struct sockaddr *, size_t sa_len,
struct vconn **);
};
-static struct vconn_class pstream_vconn_class;
+static struct pvconn_class pstream_pvconn_class;
-static struct pstream_vconn *
-pstream_vconn_cast(struct vconn *vconn)
+static struct pstream_pvconn *
+pstream_pvconn_cast(struct pvconn *pvconn)
{
- assert(vconn->class == &pstream_vconn_class);
- return CONTAINER_OF(vconn, struct pstream_vconn, vconn);
+ pvconn_assert_class(pvconn, &pstream_pvconn_class);
+ return CONTAINER_OF(pvconn, struct pstream_pvconn, pvconn);
}
int
-new_pstream_vconn(const char *name, int fd,
+new_pstream_pvconn(const char *name, int fd,
int (*accept_cb)(int fd, const struct sockaddr *,
size_t sa_len, struct vconn **),
- struct vconn **vconnp)
+ struct pvconn **pvconnp)
{
- struct pstream_vconn *ps;
+ struct pstream_pvconn *ps;
int retval;
retval = set_nonblocking(fd);
}
ps = xmalloc(sizeof *ps);
- ps->vconn.class = &pstream_vconn_class;
- ps->vconn.connect_status = 0;
+ pvconn_init(&ps->pvconn, &pstream_pvconn_class, name);
ps->fd = fd;
ps->accept_cb = accept_cb;
- *vconnp = &ps->vconn;
+ *pvconnp = &ps->pvconn;
return 0;
}
static void
-pstream_close(struct vconn *vconn)
+pstream_close(struct pvconn *pvconn)
{
- struct pstream_vconn *ps = pstream_vconn_cast(vconn);
+ struct pstream_pvconn *ps = pstream_pvconn_cast(pvconn);
close(ps->fd);
free(ps);
}
static int
-pstream_accept(struct vconn *vconn, struct vconn **new_vconnp)
+pstream_accept(struct pvconn *pvconn, struct vconn **new_vconnp)
{
- struct pstream_vconn *ps = pstream_vconn_cast(vconn);
+ struct pstream_pvconn *ps = pstream_pvconn_cast(pvconn);
struct sockaddr_storage ss;
socklen_t ss_len = sizeof ss;
int new_fd;
if (new_fd < 0) {
int retval = errno;
if (retval != EAGAIN) {
- VLOG_DBG("accept: %s", strerror(retval));
+ VLOG_DBG_RL(&rl, "accept: %s", strerror(retval));
}
return retval;
}
}
static void
-pstream_wait(struct vconn *vconn, enum vconn_wait_type wait)
+pstream_wait(struct pvconn *pvconn)
{
- struct pstream_vconn *ps = pstream_vconn_cast(vconn);
- assert(wait == WAIT_ACCEPT);
+ struct pstream_pvconn *ps = pstream_pvconn_cast(pvconn);
poll_fd_wait(ps->fd, POLLIN);
}
-static struct vconn_class pstream_vconn_class = {
- .name = "pstream",
- .close = pstream_close,
- .accept = pstream_accept,
- .wait = pstream_wait
+static struct pvconn_class pstream_pvconn_class = {
+ "pstream",
+ NULL,
+ pstream_close,
+ pstream_accept,
+ pstream_wait
};