Made TSocketHandle distinct and fixed problems it caused for SSL.

This commit is contained in:
Dominik Picheta
2013-10-23 18:07:00 +01:00
parent a352109ade
commit 8231deffd0
4 changed files with 55 additions and 30 deletions

View File

@@ -81,8 +81,7 @@ else:
## A type representing a directory stream.
type
TSocketHandle* = cint # The type used to represent socket descripters
# Should this be distinct? Is this the right place?
TSocketHandle* = distinct cint # The type used to represent socket descriptors
Tdirent* {.importc: "struct dirent",
header: "<dirent.h>", final, pure.} = object ## dirent_t struct
@@ -1794,7 +1793,7 @@ proc dlopen*(a1: cstring, a2: cint): pointer {.importc, header: "<dlfcn.h>".}
proc dlsym*(a1: pointer, a2: cstring): pointer {.importc, header: "<dlfcn.h>".}
proc creat*(a1: cstring, a2: Tmode): cint {.importc, header: "<fcntl.h>".}
proc fcntl*(a1: cint, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".}
proc fcntl*(a1: cint | TSocketHandle, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".}
proc open*(a1: cstring, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".}
proc posix_fadvise*(a1: cint, a2, a3: Toff, a4: cint): cint {.
importc, header: "<fcntl.h>".}
@@ -2071,7 +2070,7 @@ proc access*(a1: cstring, a2: cint): cint {.importc, header: "<unistd.h>".}
proc alarm*(a1: cint): cint {.importc, header: "<unistd.h>".}
proc chdir*(a1: cstring): cint {.importc, header: "<unistd.h>".}
proc chown*(a1: cstring, a2: Tuid, a3: Tgid): cint {.importc, header: "<unistd.h>".}
proc close*(a1: cint): cint {.importc, header: "<unistd.h>".}
proc close*(a1: cint | TSocketHandle): cint {.importc, header: "<unistd.h>".}
proc confstr*(a1: cint, a2: cstring, a3: int): int {.importc, header: "<unistd.h>".}
proc crypt*(a1, a2: cstring): cstring {.importc, header: "<unistd.h>".}
proc ctermid*(a1: cstring): cstring {.importc, header: "<unistd.h>".}
@@ -2349,9 +2348,9 @@ proc strerror*(errnum: cint): cstring {.importc, header: "<string.h>".}
proc hstrerror*(herrnum: cint): cstring {.importc, header: "<netdb.h>".}
proc FD_CLR*(a1: cint, a2: var Tfd_set) {.importc, header: "<sys/select.h>".}
proc FD_ISSET*(a1: cint, a2: var Tfd_set): cint {.
proc FD_ISSET*(a1: cint | TSocketHandle, a2: var Tfd_set): cint {.
importc, header: "<sys/select.h>".}
proc FD_SET*(a1: cint, a2: var Tfd_set) {.importc, header: "<sys/select.h>".}
proc FD_SET*(a1: cint | TSocketHandle, a2: var Tfd_set) {.importc, header: "<sys/select.h>".}
proc FD_ZERO*(a1: var Tfd_set) {.importc, header: "<sys/select.h>".}
proc pselect*(a1: cint, a2, a3, a4: ptr Tfd_set, a5: ptr ttimespec,
@@ -2431,44 +2430,49 @@ proc CMSG_NXTHDR*(mhdr: ptr TMsgHdr, cmsg: ptr TCMsgHdr): ptr TCmsgHdr {.
proc CMSG_FIRSTHDR*(mhdr: ptr TMsgHdr): ptr TCMsgHdr {.
importc, header: "<sys/socket.h>".}
proc accept*(a1: cint, a2: ptr Tsockaddr, a3: ptr Tsocklen): cint {.
const
INVALID_SOCKET* = TSocketHandle(-1)
proc `==`*(x, y: TSocketHandle): bool {.borrow.}
proc accept*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: ptr Tsocklen): TSocketHandle {.
importc, header: "<sys/socket.h>".}
proc bindSocket*(a1: cint, a2: ptr Tsockaddr, a3: Tsocklen): cint {.
proc bindSocket*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: Tsocklen): cint {.
importc: "bind", header: "<sys/socket.h>".}
## is Posix's ``bind``, because ``bind`` is a reserved word
proc connect*(a1: cint, a2: ptr Tsockaddr, a3: Tsocklen): cint {.
proc connect*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: Tsocklen): cint {.
importc, header: "<sys/socket.h>".}
proc getpeername*(a1: cint, a2: ptr Tsockaddr, a3: ptr Tsocklen): cint {.
proc getpeername*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: ptr Tsocklen): cint {.
importc, header: "<sys/socket.h>".}
proc getsockname*(a1: cint, a2: ptr Tsockaddr, a3: ptr Tsocklen): cint {.
proc getsockname*(a1: TSocketHandle, a2: ptr Tsockaddr, a3: ptr Tsocklen): cint {.
importc, header: "<sys/socket.h>".}
proc getsockopt*(a1, a2, a3: cint, a4: pointer, a5: ptr Tsocklen): cint {.
proc getsockopt*(a1: TSocketHandle, a2, a3: cint, a4: pointer, a5: ptr Tsocklen): cint {.
importc, header: "<sys/socket.h>".}
proc listen*(a1, a2: cint): cint {.
proc listen*(a1: TSocketHandle, a2: cint): cint {.
importc, header: "<sys/socket.h>".}
proc recv*(a1: cint, a2: pointer, a3: int, a4: cint): int {.
proc recv*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint): int {.
importc, header: "<sys/socket.h>".}
proc recvfrom*(a1: cint, a2: pointer, a3: int, a4: cint,
proc recvfrom*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint,
a5: ptr Tsockaddr, a6: ptr Tsocklen): int {.
importc, header: "<sys/socket.h>".}
proc recvmsg*(a1: cint, a2: ptr Tmsghdr, a3: cint): int {.
proc recvmsg*(a1: TSocketHandle, a2: ptr Tmsghdr, a3: cint): int {.
importc, header: "<sys/socket.h>".}
proc send*(a1: cint, a2: pointer, a3: int, a4: cint): int {.
proc send*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint): int {.
importc, header: "<sys/socket.h>".}
proc sendmsg*(a1: cint, a2: ptr Tmsghdr, a3: cint): int {.
proc sendmsg*(a1: TSocketHandle, a2: ptr Tmsghdr, a3: cint): int {.
importc, header: "<sys/socket.h>".}
proc sendto*(a1: cint, a2: pointer, a3: int, a4: cint, a5: ptr Tsockaddr,
proc sendto*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint, a5: ptr Tsockaddr,
a6: Tsocklen): int {.
importc, header: "<sys/socket.h>".}
proc setsockopt*(a1, a2, a3: cint, a4: pointer, a5: Tsocklen): cint {.
proc setsockopt*(a1: TSocketHandle, a2, a3: cint, a4: pointer, a5: Tsocklen): cint {.
importc, header: "<sys/socket.h>".}
proc shutdown*(a1, a2: cint): cint {.
proc shutdown*(a1: TSocketHandle, a2: cint): cint {.
importc, header: "<sys/socket.h>".}
proc socket*(a1, a2, a3: cint): cint {.
proc socket*(a1, a2, a3: cint): TSocketHandle {.
importc, header: "<sys/socket.h>".}
proc sockatmark*(a1: cint): cint {.
importc, header: "<sys/socket.h>".}

View File

@@ -126,7 +126,19 @@ type
ETimeout* = object of ESynch
let
InvalidSocket*: TSocket = nil ## invalid socket
when defined(windows):
const
OSInvalidSocket = winlean.INVALID_SOCKET
else:
const
OSInvalidSocket = posix.INVALID_SOCKET
proc newTSocket(fd: TSocketHandle, isBuff: bool): TSocket =
if fd == OSInvalidSocket:
return nil
new(result)
result.fd = fd
result.isBuffered = isBuff
@@ -134,9 +146,6 @@ proc newTSocket(fd: TSocketHandle, isBuff: bool): TSocket =
result.currPos = 0
result.nonblocking = false
let
InvalidSocket*: TSocket = nil ## invalid socket
proc `==`*(a, b: TPort): bool {.borrow.}
## ``==`` for ports.
@@ -211,7 +220,9 @@ else:
proc socket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM,
protocol: TProtocol = IPPROTO_TCP, buffered = true): TSocket =
## Creates a new socket; returns `InvalidSocket` if an error occurs.
## Creates a new socket; returns `InvalidSocket` if an error occurs.
# TODO: Perhaps this should just raise EOS when an error occurs.
when defined(Windows):
result = newTSocket(winlean.socket(ord(domain), ord(typ), ord(protocol)), buffered)
else:
@@ -456,7 +467,7 @@ template acceptAddrPlain(noClientRet, successRet: expr,
var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)),
addr(addrLen))
if sock < 0:
if sock == OSInvalidSocket:
let err = OSLastError()
when defined(windows):
if err.int32 == WSAEINPROGRESS:

View File

@@ -389,8 +389,6 @@ type
h_addrtype*: int16
h_length*: int16
h_addr_list*: cstringArray
TSocketHandle* = int # Make distinct? Is this the right place for this?
TFdSet* {.pure, final.} = object
fd_count*: cint # unsigned
@@ -411,8 +409,18 @@ type
Tsocklen* = cuint
when hostCPU == "amd64":
type
TSocketHandle* = distinct int # on WIN64 `SOCKET` is UINT_PTR
else:
type
TSocketHandle* = distinct cuint # on WIN32 `SOCKET` is U_INT (unsigned int)
var
SOMAXCONN* {.importc, header: "Winsock2.h".}: cint
INVALID_SOCKET* {.importc, header: "Winsock2.h".}: cint
proc `==`*(x, y: TSocketHandle): bool {.borrow.}
proc getservbyname*(name, proto: cstring): ptr TServent {.
stdcall, importc: "getservbyname", dynlib: ws2dll.}

View File

@@ -45,6 +45,7 @@ when defined(WINDOWS):
const
DLLSSLName = "(ssleay32|libssl32).dll"
DLLUtilName = "libeay32.dll"
from winlean import TSocketHandle
else:
const
versions = "(|.1.0.0|.0.9.9|.0.9.8|.0.9.7|.0.9.6|.0.9.5|.0.9.4)"
@@ -56,6 +57,7 @@ else:
const
DLLSSLName = "libssl.so" & versions
DLLUtilName = "libcrypto.so" & versions
from posix import TSocketHandle
type
SslStruct {.final, pure.} = object
@@ -225,7 +227,7 @@ proc SSL_CTX_use_PrivateKey_file*(ctx: PSSL_CTX,
proc SSL_CTX_check_private_key*(ctx: PSSL_CTX): cInt{.cdecl, dynlib: DLLSSLName,
importc.}
proc SSL_set_fd*(ssl: PSSL, fd: cint): cint{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_set_fd*(ssl: PSSL, fd: TSocketHandle): cint{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_shutdown*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_connect*(ssl: PSSL): cint{.cdecl, dynlib: DLLSSLName, importc.}