summaryrefslogtreecommitdiff
path: root/usr.sbin/switchd/util.c
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2016-09-30 11:57:58 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2016-09-30 11:57:58 +0000
commit34e7ea606a2a7c495e17bc87fd503fe38c88342f (patch)
tree2edd0a72884707e0683ca9e867758fea67ef9a0f /usr.sbin/switchd/util.c
parent2b6f59f4862e957035fa91b52a33c7cf0a32061b (diff)
Implement socket server code that properly handles async I/O, partial
messages, multiple messages per buffer and important things like connection limits and file descriptor accounting. It works with TCP connections as well as switch(4). The ofrelay.c part replaces networking that was in ofp.c and will soon handle all socket connections of switchd. It is called "ofrelay" because it will be used as client, server, and forwarder. OK rzalamena@
Diffstat (limited to 'usr.sbin/switchd/util.c')
-rw-r--r--usr.sbin/switchd/util.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/usr.sbin/switchd/util.c b/usr.sbin/switchd/util.c
index 716423c7460..c0066d081be 100644
--- a/usr.sbin/switchd/util.c
+++ b/usr.sbin/switchd/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.3 2016/09/29 20:46:06 reyk Exp $ */
+/* $OpenBSD: util.c,v 1.4 2016/09/30 11:57:57 reyk Exp $ */
/*
* Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
@@ -26,11 +26,13 @@
#include <netinet/if_ether.h>
#include <netinet/tcp.h>
+#include <unistd.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
+#include <errno.h>
#include <event.h>
#include "switchd.h"
@@ -55,6 +57,25 @@ socket_set_blockmode(int fd, enum blockmodes bm)
fatal("fcntl F_SETFL");
}
+int
+accept4_reserve(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
+ int flags, int reserve, volatile int *counter)
+{
+ int fd;
+
+ if (getdtablecount() + reserve + *counter >= getdtablesize()) {
+ errno = EMFILE;
+ return (-1);
+ }
+
+ if ((fd = accept4(sockfd, addr, addrlen, flags)) != -1) {
+ (*counter)++;
+ DPRINTF("%s: inflight incremented, now %d",__func__, *counter);
+ }
+
+ return (fd);
+}
+
in_port_t
socket_getport(struct sockaddr_storage *ss)
{