Fixes net/asyncdispatch on Windows. Ref #2976. Fixes #2996.

This commit is contained in:
Dominik Picheta 2015-06-25 22:36:53 +01:00
commit 6109e6a999
3 changed files with 59 additions and 47 deletions

View file

@ -483,7 +483,7 @@ when defined(windows) or defined(nimdoc):
RemoteSockaddr, RemoteSockaddrLength) RemoteSockaddr, RemoteSockaddrLength)
proc connect*(socket: AsyncFD, address: string, port: Port, proc connect*(socket: AsyncFD, address: string, port: Port,
af = AF_INET): Future[void] = af = rawsockets.AF_INET): Future[void] =
## Connects ``socket`` to server at ``address:port``. ## Connects ``socket`` to server at ``address:port``.
## ##
## Returns a ``Future`` which will complete when the connection succeeds ## Returns a ``Future`` which will complete when the connection succeeds
@ -861,7 +861,7 @@ when defined(windows) or defined(nimdoc):
result.SocketHandle.setBlocking(false) result.SocketHandle.setBlocking(false)
register(result) register(result)
proc newAsyncRawSocket*(domain: Domain = AF_INET, proc newAsyncRawSocket*(domain: Domain = rawsockets.AF_INET,
typ: SockType = SOCK_STREAM, typ: SockType = SOCK_STREAM,
protocol: Protocol = IPPROTO_TCP): AsyncFD = protocol: Protocol = IPPROTO_TCP): AsyncFD =
## Creates a new socket and registers it with the dispatcher implicitly. ## Creates a new socket and registers it with the dispatcher implicitly.

View file

@ -27,9 +27,10 @@ else:
import posix import posix
export fcntl, F_GETFL, O_NONBLOCK, F_SETFL, EAGAIN, EWOULDBLOCK, MSG_NOSIGNAL, export fcntl, F_GETFL, O_NONBLOCK, F_SETFL, EAGAIN, EWOULDBLOCK, MSG_NOSIGNAL,
EINTR, EINPROGRESS, ECONNRESET, EPIPE, ENETRESET EINTR, EINPROGRESS, ECONNRESET, EPIPE, ENETRESET
export Sockaddr_storage
export SocketHandle, Sockaddr_in, Addrinfo, INADDR_ANY, SockAddr, SockLen, export SocketHandle, Sockaddr_in, Addrinfo, INADDR_ANY, SockAddr, SockLen,
Sockaddr_in6, Sockaddr_storage, Sockaddr_in6,
inet_ntoa, recv, `==`, connect, send, accept, recvfrom, sendto inet_ntoa, recv, `==`, connect, send, accept, recvfrom, sendto
export export
@ -92,6 +93,8 @@ when useWinVersion:
IOC_IN* = int(-2147483648) IOC_IN* = int(-2147483648)
FIONBIO* = IOC_IN.int32 or ((sizeof(int32) and IOCPARM_MASK) shl 16) or FIONBIO* = IOC_IN.int32 or ((sizeof(int32) and IOCPARM_MASK) shl 16) or
(102 shl 8) or 126 (102 shl 8) or 126
rawAfInet = winlean.AF_INET
rawAfInet6 = winlean.AF_INET6
proc ioctlsocket*(s: SocketHandle, cmd: clong, proc ioctlsocket*(s: SocketHandle, cmd: clong,
argptr: ptr clong): cint {. argptr: ptr clong): cint {.
@ -99,6 +102,8 @@ when useWinVersion:
else: else:
let let
osInvalidSocket* = posix.INVALID_SOCKET osInvalidSocket* = posix.INVALID_SOCKET
rawAfInet = posix.AF_INET
rawAfInet6 = posix.AF_INET6
proc `==`*(a, b: Port): bool {.borrow.} proc `==`*(a, b: Port): bool {.borrow.}
## ``==`` for ports. ## ``==`` for ports.
@ -195,7 +200,7 @@ proc getAddrInfo*(address: string, port: Port, af: Domain = AF_INET, typ: SockTy
hints.ai_family = toInt(af) hints.ai_family = toInt(af)
hints.ai_socktype = toInt(typ) hints.ai_socktype = toInt(typ)
hints.ai_protocol = toInt(prot) hints.ai_protocol = toInt(prot)
hints.ai_flags = posix.AI_V4MAPPED hints.ai_flags = AI_V4MAPPED
var gaiResult = getaddrinfo(address, $port, addr(hints), result) var gaiResult = getaddrinfo(address, $port, addr(hints), result)
if gaiResult != 0'i32: if gaiResult != 0'i32:
when useWinVersion: when useWinVersion:
@ -324,9 +329,9 @@ proc getSockDomain*(socket: SocketHandle): Domain =
if getsockname(socket, cast[ptr SockAddr](addr(name)), if getsockname(socket, cast[ptr SockAddr](addr(name)),
addr(namelen)) == -1'i32: addr(namelen)) == -1'i32:
raiseOSError(osLastError()) raiseOSError(osLastError())
if name.sa_family == posix.AF_INET: if name.sa_family == rawAfInet:
result = AF_INET result = AF_INET
elif name.sa_family == posix.AF_INET6: elif name.sa_family == rawAfInet6:
result = AF_INET6 result = AF_INET6
else: else:
raise newException(OSError, "unknown socket family in getSockFamily") raise newException(OSError, "unknown socket family in getSockFamily")
@ -334,13 +339,17 @@ proc getSockDomain*(socket: SocketHandle): Domain =
proc getAddrString*(sockAddr: ptr SockAddr): string = proc getAddrString*(sockAddr: ptr SockAddr): string =
## return the string representation of address within sockAddr ## return the string representation of address within sockAddr
if sockAddr.sa_family == posix.AF_INET: if sockAddr.sa_family == rawAfInet:
result = $inet_ntoa(cast[ptr Sockaddr_in](sockAddr).sin_addr) result = $inet_ntoa(cast[ptr Sockaddr_in](sockAddr).sin_addr)
elif sockAddr.sa_family == posix.AF_INET6: elif sockAddr.sa_family == rawAfInet6:
when not useWinVersion:
# TODO: Windows
var v6addr = cast[ptr Sockaddr_in6](sockAddr).sin6_addr var v6addr = cast[ptr Sockaddr_in6](sockAddr).sin6_addr
result = newString(posix.INET6_ADDRSTRLEN) result = newString(posix.INET6_ADDRSTRLEN)
discard posix.inet_ntop(posix.AF_INET6, addr cast[ptr Sockaddr_in6](sockAddr).sin6_addr, result.cstring, result.len.int32) let addr6 = addr cast[ptr Sockaddr_in6](sockAddr).sin6_addr
if posix.IN6_IS_ADDR_V4MAPPED(addr cast[ptr Sockaddr_in6](sockAddr).sin6_addr) != 0: discard posix.inet_ntop(posix.AF_INET6, addr6, result.cstring,
result.len.int32)
if posix.IN6_IS_ADDR_V4MAPPED(addr6) != 0:
result = result.substr("::ffff:".len) result = result.substr("::ffff:".len)
else: else:
raise newException(OSError, "unknown socket family in getAddrString") raise newException(OSError, "unknown socket family in getAddrString")

View file

@ -723,6 +723,9 @@ template WSAIORW*(x,y): expr = (IOC_INOUT or x or y)
const const
SIO_GET_EXTENSION_FUNCTION_POINTER* = WSAIORW(IOC_WS2,6).DWORD SIO_GET_EXTENSION_FUNCTION_POINTER* = WSAIORW(IOC_WS2,6).DWORD
SO_UPDATE_ACCEPT_CONTEXT* = 0x700B SO_UPDATE_ACCEPT_CONTEXT* = 0x700B
AI_V4MAPPED* = 0x0008
AF_INET* = 2
AF_INET6* = 23
var var
WSAID_CONNECTEX*: GUID = GUID(D1: 0x25a207b9, D2: 0xddf3'i16, D3: 0x4660, D4: [ WSAID_CONNECTEX*: GUID = GUID(D1: 0x25a207b9, D2: 0xddf3'i16, D3: 0x4660, D4: [