Define ports as uint16s to fix #3484

This commit is contained in:
Josep Sanjuas 2016-03-27 22:56:05 +02:00
commit 5a582a0d9c
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. ## order, this is a no-op; otherwise, it performs a 2-byte swap operation.
result = sockets.ntohs(x) 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): when defined(Posix):
proc toInt(domain: Domain): cint = proc toInt(domain: Domain): cint =
case domain case domain
@ -451,7 +463,7 @@ proc bindAddr*(socket: Socket, port = Port(0), address = "") {.
name.sin_family = int16(ord(AF_INET)) name.sin_family = int16(ord(AF_INET))
else: else:
name.sin_family = posix.AF_INET 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) name.sin_addr.s_addr = sockets.htonl(INADDR_ANY)
if bindSocket(socket.fd, cast[ptr SockAddr](addr(name)), if bindSocket(socket.fd, cast[ptr SockAddr](addr(name)),
sizeof(name).SockLen) < 0'i32: sizeof(name).SockLen) < 0'i32:
@ -834,7 +846,7 @@ proc connect*(socket: Socket, address: string, port = Port(0),
when false: when false:
var s: TSockAddrIn var s: TSockAddrIn
s.sin_addr.s_addr = inet_addr(address) 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): when defined(windows):
s.sin_family = toU16(ord(af)) s.sin_family = toU16(ord(af))
else: else:

View file

@ -486,11 +486,11 @@ type
l_onoff*: cint ## Indicates whether linger option is enabled. l_onoff*: cint ## Indicates whether linger option is enabled.
l_linger*: cint ## Linger time, in seconds. l_linger*: cint ## Linger time, in seconds.
InPort* = int16 ## unsigned! InPort* = uint16
InAddrScalar* = int32 ## unsigned! InAddrScalar* = uint32
InAddrT* {.importc: "in_addr_t", pure, final, 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, InAddr* {.importc: "struct in_addr", pure, final,
header: "<netinet/in.h>".} = object ## struct in_addr 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) = proc dealloc*(ai: ptr AddrInfo) =
freeaddrinfo(ai) freeaddrinfo(ai)
proc ntohl*(x: int32): int32 = proc ntohl*(x: uint32): uint32 =
## Converts 32-bit integers from network to host byte order. ## 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, ## 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. ## this is a no-op; otherwise, it performs a 4-byte swap operation.
when cpuEndian == bigEndian: result = x when cpuEndian == bigEndian: result = x
else: result = (x shr 24'i32) or else: result = (x shr 24'u32) or
(x shr 8'i32 and 0xff00'i32) or (x shr 8'u32 and 0xff00'u32) or
(x shl 8'i32 and 0xff0000'i32) or (x shl 8'u32 and 0xff0000'u32) or
(x shl 24'i32) (x shl 24'u32)
proc ntohs*(x: int16): int16 = template ntohl*(x: int32): expr {.deprecated.} =
## Converts 16-bit integers from network to host byte order. On machines ## Converts 32-bit integers from network to host byte order.
## where the host byte order is the same as network byte order, this is ## On machines where the host byte order is the same as network byte order,
## a no-op; otherwise, it performs a 2-byte swap operation. ## 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 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 ## 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 ## 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. ## 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) nativesockets.ntohl(x)
template htons*(x: int16): expr = template htonl*(x: uint32): expr =
## Converts 16-bit positive integers from host to network byte order. ## 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 ## 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. ## order, this is a no-op; otherwise, it performs a 2-byte swap operation.
nativesockets.ntohs(x) nativesockets.ntohs(x)

View file

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

View file

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