From e174aa1dbccd6c5c5b6a05543da41158c3e2c374 Mon Sep 17 00:00:00 2001 From: Federico Ceratto Date: Tue, 15 Dec 2015 23:50:28 +0000 Subject: [PATCH] Add SO_REUSEPORT support --- lib/posix/posix.nim | 2 ++ lib/pure/asynchttpserver.nim | 6 +++++- lib/pure/nativesockets.nim | 2 +- lib/pure/net.nim | 3 ++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index 5f1dfcfcd5..c3d563419c 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -1566,6 +1566,8 @@ var ## Receive timeout. SO_REUSEADDR* {.importc, header: "".}: cint ## Reuse of local addresses is supported. + SO_REUSEPORT* {.importc, header: "".}: cint + ## Multiple binding: load balancing on incoming TCP connections or UDP packets. (Requires Linux kernel > 3.9) SO_SNDBUF* {.importc, header: "".}: cint ## Send buffer size. SO_SNDLOWAT* {.importc, header: "".}: cint diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index 590b52c1a2..865b14c751 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -39,6 +39,7 @@ type AsyncHttpServer* = ref object socket: AsyncSocket reuseAddr: bool + reusePort: bool HttpCode* = enum Http100 = "100 Continue", @@ -99,10 +100,11 @@ proc `==`*(protocol: tuple[orig: string, major, minor: int], of HttpVer10: 0 result = protocol.major == major and protocol.minor == minor -proc newAsyncHttpServer*(reuseAddr = true): AsyncHttpServer = +proc newAsyncHttpServer*(reuseAddr = true, reusePort = false): AsyncHttpServer = ## Creates a new ``AsyncHttpServer`` instance. new result result.reuseAddr = reuseAddr + result.reusePort = reusePort proc addHeaders(msg: var string, headers: StringTableRef) = for k, v in headers: @@ -264,6 +266,8 @@ proc serve*(server: AsyncHttpServer, port: Port, server.socket = newAsyncSocket() if server.reuseAddr: server.socket.setSockOpt(OptReuseAddr, true) + if server.reusePort: + server.socket.setSockOpt(OptReusePort, true) server.socket.bindAddr(port, address) server.socket.listen() diff --git a/lib/pure/nativesockets.nim b/lib/pure/nativesockets.nim index 8a77805704..37e3773c5a 100644 --- a/lib/pure/nativesockets.nim +++ b/lib/pure/nativesockets.nim @@ -38,7 +38,7 @@ export SOL_SOCKET, SOMAXCONN, SO_ACCEPTCONN, SO_BROADCAST, SO_DEBUG, SO_DONTROUTE, - SO_KEEPALIVE, SO_OOBINLINE, SO_REUSEADDR, + SO_KEEPALIVE, SO_OOBINLINE, SO_REUSEADDR, SO_REUSEPORT, MSG_PEEK when defined(macosx) and not defined(nimdoc): diff --git a/lib/pure/net.nim b/lib/pure/net.nim index d1016011e4..1243201ab3 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -72,7 +72,7 @@ type SOBool* = enum ## Boolean socket options. OptAcceptConn, OptBroadcast, OptDebug, OptDontRoute, OptKeepAlive, - OptOOBInline, OptReuseAddr + OptOOBInline, OptReuseAddr, OptReusePort ReadLineResult* = enum ## result for readLineAsync ReadFullLine, ReadPartialLine, ReadDisconnected, ReadNone @@ -523,6 +523,7 @@ proc toCInt*(opt: SOBool): cint = of OptKeepAlive: SO_KEEPALIVE of OptOOBInline: SO_OOBINLINE of OptReuseAddr: SO_REUSEADDR + of OptReusePort: SO_REUSEPORT proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {. tags: [ReadIOEffect].} =