Merge pull request #3648 from FedericoCeratto/reuse_port

Add SO_REUSEPORT support
This commit is contained in:
Andreas Rumpf 2016-05-29 22:21:56 +02:00
commit 380524caa8
4 changed files with 10 additions and 3 deletions

View file

@ -1575,6 +1575,8 @@ var
## Receive timeout. ## Receive timeout.
SO_REUSEADDR* {.importc, header: "<sys/socket.h>".}: cint SO_REUSEADDR* {.importc, header: "<sys/socket.h>".}: cint
## Reuse of local addresses is supported. ## Reuse of local addresses is supported.
SO_REUSEPORT* {.importc, header: "<sys/socket.h>".}: cint
## Multiple binding: load balancing on incoming TCP connections or UDP packets. (Requires Linux kernel > 3.9)
SO_SNDBUF* {.importc, header: "<sys/socket.h>".}: cint SO_SNDBUF* {.importc, header: "<sys/socket.h>".}: cint
## Send buffer size. ## Send buffer size.
SO_SNDLOWAT* {.importc, header: "<sys/socket.h>".}: cint SO_SNDLOWAT* {.importc, header: "<sys/socket.h>".}: cint

View file

@ -39,6 +39,7 @@ type
AsyncHttpServer* = ref object AsyncHttpServer* = ref object
socket: AsyncSocket socket: AsyncSocket
reuseAddr: bool reuseAddr: bool
reusePort: bool
HttpCode* = enum HttpCode* = enum
Http100 = "100 Continue", Http100 = "100 Continue",
@ -99,10 +100,11 @@ proc `==`*(protocol: tuple[orig: string, major, minor: int],
of HttpVer10: 0 of HttpVer10: 0
result = protocol.major == major and protocol.minor == minor 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. ## Creates a new ``AsyncHttpServer`` instance.
new result new result
result.reuseAddr = reuseAddr result.reuseAddr = reuseAddr
result.reusePort = reusePort
proc addHeaders(msg: var string, headers: StringTableRef) = proc addHeaders(msg: var string, headers: StringTableRef) =
for k, v in headers: for k, v in headers:
@ -264,6 +266,8 @@ proc serve*(server: AsyncHttpServer, port: Port,
server.socket = newAsyncSocket() server.socket = newAsyncSocket()
if server.reuseAddr: if server.reuseAddr:
server.socket.setSockOpt(OptReuseAddr, true) server.socket.setSockOpt(OptReuseAddr, true)
if server.reusePort:
server.socket.setSockOpt(OptReusePort, true)
server.socket.bindAddr(port, address) server.socket.bindAddr(port, address)
server.socket.listen() server.socket.listen()

View file

@ -38,7 +38,7 @@ export
SOL_SOCKET, SOL_SOCKET,
SOMAXCONN, SOMAXCONN,
SO_ACCEPTCONN, SO_BROADCAST, SO_DEBUG, SO_DONTROUTE, SO_ACCEPTCONN, SO_BROADCAST, SO_DEBUG, SO_DONTROUTE,
SO_KEEPALIVE, SO_OOBINLINE, SO_REUSEADDR, SO_KEEPALIVE, SO_OOBINLINE, SO_REUSEADDR, SO_REUSEPORT,
MSG_PEEK MSG_PEEK
when defined(macosx) and not defined(nimdoc): when defined(macosx) and not defined(nimdoc):

View file

@ -129,7 +129,7 @@ type
SOBool* = enum ## Boolean socket options. SOBool* = enum ## Boolean socket options.
OptAcceptConn, OptBroadcast, OptDebug, OptDontRoute, OptKeepAlive, OptAcceptConn, OptBroadcast, OptDebug, OptDontRoute, OptKeepAlive,
OptOOBInline, OptReuseAddr OptOOBInline, OptReuseAddr, OptReusePort
ReadLineResult* = enum ## result for readLineAsync ReadLineResult* = enum ## result for readLineAsync
ReadFullLine, ReadPartialLine, ReadDisconnected, ReadNone ReadFullLine, ReadPartialLine, ReadDisconnected, ReadNone
@ -579,6 +579,7 @@ proc toCInt*(opt: SOBool): cint =
of OptKeepAlive: SO_KEEPALIVE of OptKeepAlive: SO_KEEPALIVE
of OptOOBInline: SO_OOBINLINE of OptOOBInline: SO_OOBINLINE
of OptReuseAddr: SO_REUSEADDR of OptReuseAddr: SO_REUSEADDR
of OptReusePort: SO_REUSEPORT
proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {. proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {.
tags: [ReadIOEffect].} = tags: [ReadIOEffect].} =