Merge pull request #3486 from jsanjuas/devel

Allow binding to ports >= 32768, fixes #3484
This commit is contained in:
Dominik Picheta
2016-03-27 22:38:27 +01:00
6 changed files with 74 additions and 26 deletions

View File

@@ -206,6 +206,18 @@ proc htons*(x: int16): int16 =
## order, this is a no-op; otherwise, it performs a 2-byte swap operation.
result = sockets.ntohs(x)
template ntohl(x: uint32): expr =
cast[uint32](sockets.ntohl(cast[int32](x)))
template ntohs(x: uint16): expr =
cast[uint16](sockets.ntohs(cast[int16](x)))
template htonl(x: uint32): expr =
sockets.ntohl(x)
template htons(x: uint16): expr =
sockets.ntohs(x)
when defined(Posix):
proc toInt(domain: Domain): cint =
case domain
@@ -451,7 +463,7 @@ proc bindAddr*(socket: Socket, port = Port(0), address = "") {.
name.sin_family = int16(ord(AF_INET))
else:
name.sin_family = posix.AF_INET
name.sin_port = sockets.htons(int16(port))
name.sin_port = sockets.htons(uint16(port))
name.sin_addr.s_addr = sockets.htonl(INADDR_ANY)
if bindSocket(socket.fd, cast[ptr SockAddr](addr(name)),
sizeof(name).SockLen) < 0'i32:
@@ -834,7 +846,7 @@ proc connect*(socket: Socket, address: string, port = Port(0),
when false:
var s: TSockAddrIn
s.sin_addr.s_addr = inet_addr(address)
s.sin_port = sockets.htons(int16(port))
s.sin_port = sockets.htons(uint16(port))
when defined(windows):
s.sin_family = toU16(ord(af))
else:

View File

@@ -486,11 +486,11 @@ type
l_onoff*: cint ## Indicates whether linger option is enabled.
l_linger*: cint ## Linger time, in seconds.
InPort* = int16 ## unsigned!
InAddrScalar* = int32 ## unsigned!
InPort* = uint16
InAddrScalar* = uint32
InAddrT* {.importc: "in_addr_t", pure, final,
header: "<netinet/in.h>".} = int32 ## unsigned!
header: "<netinet/in.h>".} = uint32
InAddr* {.importc: "struct in_addr", pure, final,
header: "<netinet/in.h>".} = object ## struct in_addr

View File

@@ -219,31 +219,67 @@ proc getAddrInfo*(address: string, port: Port, domain: Domain = AF_INET,
proc dealloc*(ai: ptr AddrInfo) =
freeaddrinfo(ai)
proc ntohl*(x: int32): int32 =
## Converts 32-bit integers from network to host byte order.
proc ntohl*(x: uint32): uint32 =
## Converts 32-bit unsigned integers from network to host byte order.
## On machines where the host byte order is the same as network byte order,
## this is a no-op; otherwise, it performs a 4-byte swap operation.
when cpuEndian == bigEndian: result = x
else: result = (x shr 24'i32) or
(x shr 8'i32 and 0xff00'i32) or
(x shl 8'i32 and 0xff0000'i32) or
(x shl 24'i32)
else: result = (x shr 24'u32) or
(x shr 8'u32 and 0xff00'u32) or
(x shl 8'u32 and 0xff0000'u32) or
(x shl 24'u32)
proc ntohs*(x: int16): int16 =
## Converts 16-bit integers from network to host byte order. On machines
## where the host byte order is the same as network byte order, this is
## a no-op; otherwise, it performs a 2-byte swap operation.
template ntohl*(x: int32): expr {.deprecated.} =
## Converts 32-bit integers from network to host byte order.
## On machines where the host byte order is the same as network byte order,
## this is a no-op; otherwise, it performs a 4-byte swap operation.
## **Warning**: This template is deprecated since 0.14.0, IPv4
## addresses are now treated as unsigned integers. Please use the unsigned
## version of this template.
cast[int32](ntohl(cast[uint32](x)))
proc ntohs*(x: uint16): uint16 =
## Converts 16-bit unsigned integers from network to host byte order. On
## machines where the host byte order is the same as network byte order,
## this is a no-op; otherwise, it performs a 2-byte swap operation.
when cpuEndian == bigEndian: result = x
else: result = (x shr 8'i16) or (x shl 8'i16)
else: result = (x shr 8'u16) or (x shl 8'u16)
template htonl*(x: int32): expr =
template ntohs*(x: int16): expr {.deprecated.} =
## Converts 16-bit integers from network to host byte order. On
## machines where the host byte order is the same as network byte order,
## this is a no-op; otherwise, it performs a 2-byte swap operation.
## **Warning**: This template is deprecated since 0.14.0, where port
## numbers became unsigned integers. Please use the unsigned version of
## this template.
cast[int16](ntohs(cast[uint16](x)))
template htonl*(x: int32): expr {.deprecated.} =
## Converts 32-bit integers from host to network byte order. On machines
## where the host byte order is the same as network byte order, this is
## a no-op; otherwise, it performs a 4-byte swap operation.
## **Warning**: This template is deprecated since 0.14.0, IPv4
## addresses are now treated as unsigned integers. Please use the unsigned
## version of this template.
nativesockets.ntohl(x)
template htons*(x: int16): expr =
## Converts 16-bit positive integers from host to network byte order.
template htonl*(x: uint32): expr =
## Converts 32-bit unsigned integers from host to network byte order. On
## machines where the host byte order is the same as network byte order,
## this is a no-op; otherwise, it performs a 4-byte swap operation.
nativesockets.ntohl(x)
template htons*(x: int16): expr {.deprecated.} =
## Converts 16-bit integers from host to network byte order.
## On machines where the host byte order is the same as network byte
## order, this is a no-op; otherwise, it performs a 2-byte swap operation.
## **Warning**: This template is deprecated since 0.14.0, where port
## numbers became unsigned integers. Please use the unsigned version of
## this template.
nativesockets.ntohs(x)
template htons*(x: uint16): expr =
## Converts 16-bit unsigned integers from host to network byte order.
## On machines where the host byte order is the same as network byte
## order, this is a no-op; otherwise, it performs a 2-byte swap operation.
nativesockets.ntohs(x)

View File

@@ -368,7 +368,7 @@ proc bindAddr*(socket: Socket, port = Port(0), address = "") {.
name.sin_family = toInt(AF_INET).int16
else:
name.sin_family = toInt(AF_INET)
name.sin_port = htons(int16(port))
name.sin_port = htons(port.uint16)
name.sin_addr.s_addr = htonl(INADDR_ANY)
if bindAddr(socket.fd, cast[ptr SockAddr](addr(name)),
sizeof(name).SockLen) < 0'i32:

View File

@@ -412,7 +412,7 @@ const
FD_SETSIZE* = 64
MSG_PEEK* = 2
INADDR_ANY* = 0
INADDR_ANY* = 0'u32
INADDR_LOOPBACK* = 0x7F000001
INADDR_BROADCAST* = -1
INADDR_NONE* = -1
@@ -441,12 +441,12 @@ type
sa_data: array[0..13, char]
InAddr* {.importc: "IN_ADDR", header: "winsock2.h".} = object
s_addr*: int32 # IP address
s_addr*: uint32 # IP address
Sockaddr_in* {.importc: "SOCKADDR_IN",
header: "winsock2.h".} = object
sin_family*: int16
sin_port*: int16 # unsigned
sin_port*: uint16
sin_addr*: InAddr
sin_zero*: array[0..7, char]
@@ -456,7 +456,7 @@ type
Sockaddr_in6* {.importc: "SOCKADDR_IN6",
header: "ws2tcpip.h".} = object
sin6_family*: int16
sin6_port*: int16 # unsigned
sin6_port*: uint16
sin6_flowinfo*: int32 # unsigned
sin6_addr*: In6_addr
sin6_scope_id*: int32 # unsigned
@@ -590,7 +590,7 @@ proc getnameinfo*(a1: ptr SockAddr, a2: SockLen,
a6: SockLen, a7: cint): cint {.
stdcall, importc: "getnameinfo", dynlib: ws2dll.}
proc inet_addr*(cp: cstring): int32 {.
proc inet_addr*(cp: cstring): uint32 {.
stdcall, importc: "inet_addr", dynlib: ws2dll.}
proc WSAFDIsSet(s: SocketHandle, set: var TFdSet): bool {.

View File

@@ -45,7 +45,7 @@ proc createServer(port: TPort) {.async.} =
name.sin_family = toInt(AF_INET).int16
else:
name.sin_family = toInt(AF_INET)
name.sin_port = htons(int16(port))
name.sin_port = htons(uint16(port))
name.sin_addr.s_addr = htonl(INADDR_ANY)
if bindAddr(server.SocketHandle, cast[ptr SockAddr](addr(name)),
sizeof(name).Socklen) < 0'i32: