Fix remoteAddress() should raise TransportAbortedError too. (#409)

Add ENOTCONN as TransportAbortedError.
Refactor remoteAddress()/localAddress().
This commit is contained in:
Eugene Kabanov 2023-06-26 16:31:09 +03:00 committed by GitHub
parent 73fd1206ab
commit 94ca0c3847
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 23 deletions

View File

@ -574,10 +574,8 @@ template getTransportUseClosedError*(): ref TransportUseClosedError =
newException(TransportUseClosedError, "Transport is already closed!")
template getTransportOsError*(err: OSErrorCode): ref TransportOsError =
var msg = "(" & $int(err) & ") " & osErrorMsg(err)
var tre = newException(TransportOsError, msg)
tre.code = err
tre
(ref TransportOsError)(
code: err, msg: "(" & $int(err) & ") " & osErrorMsg(err))
template getTransportOsError*(err: cint): ref TransportOsError =
getTransportOsError(OSErrorCode(err))
@ -608,15 +606,16 @@ template getTransportTooManyError*(
): ref TransportTooManyError =
let msg =
when defined(posix):
if code == OSErrorCode(0):
case code
of OSErrorCode(0):
"Too many open transports"
elif code == oserrno.EMFILE:
of EMFILE:
"[EMFILE] Too many open files in the process"
elif code == oserrno.ENFILE:
of ENFILE:
"[ENFILE] Too many open files in system"
elif code == oserrno.ENOBUFS:
of ENOBUFS:
"[ENOBUFS] No buffer space available"
elif code == oserrno.ENOMEM:
of ENOMEM:
"[ENOMEM] Not enough memory availble"
else:
"[" & $int(code) & "] Too many open transports"
@ -649,23 +648,26 @@ template getConnectionAbortedError*(
): ref TransportAbortedError =
let msg =
when defined(posix):
if code == OSErrorCode(0):
case code
of OSErrorCode(0), ECONNABORTED:
"[ECONNABORTED] Connection has been aborted before being accepted"
elif code == oserrno.EPERM:
of EPERM:
"[EPERM] Firewall rules forbid connection"
elif code == oserrno.ETIMEDOUT:
of ETIMEDOUT:
"[ETIMEDOUT] Operation has been timed out"
of ENOTCONN:
"[ENOTCONN] Transport endpoint is not connected"
else:
"[" & $int(code) & "] Connection has been aborted"
elif defined(windows):
case code
of OSErrorCode(0), oserrno.WSAECONNABORTED:
of OSErrorCode(0), WSAECONNABORTED:
"[ECONNABORTED] Connection has been aborted before being accepted"
of WSAENETDOWN:
"[ENETDOWN] Network is down"
of oserrno.WSAENETRESET:
of WSAENETRESET:
"[ENETRESET] Network dropped connection on reset"
of oserrno.WSAECONNRESET:
of WSAECONNRESET:
"[ECONNRESET] Connection reset by peer"
of WSAETIMEDOUT:
"[ETIMEDOUT] Connection timed out"
@ -675,3 +677,42 @@ template getConnectionAbortedError*(
"[" & $int(code) & "] Connection has been aborted"
newException(TransportAbortedError, msg)
template getTransportError*(ecode: OSErrorCode): untyped =
when defined(posix):
case ecode
of ECONNABORTED, EPERM, ETIMEDOUT, ENOTCONN:
getConnectionAbortedError(ecode)
of EMFILE, ENFILE, ENOBUFS, ENOMEM:
getTransportTooManyError(ecode)
else:
getTransportOsError(ecode)
else:
case ecode
of WSAECONNABORTED, WSAENETDOWN, WSAENETRESET, WSAECONNRESET, WSAETIMEDOUT:
getConnectionAbortedError(ecode)
of ERROR_TOO_MANY_OPEN_FILES, WSAENOBUFS, WSAEMFILE:
getTransportTooManyError(ecode)
else:
getTransportOsError(ecode)
proc raiseTransportError*(ecode: OSErrorCode) {.
raises: [TransportAbortedError, TransportTooManyError, TransportOsError],
noreturn.} =
## Raises transport specific OS error.
when defined(posix):
case ecode
of ECONNABORTED, EPERM, ETIMEDOUT, ENOTCONN:
raise getConnectionAbortedError(ecode)
of EMFILE, ENFILE, ENOBUFS, ENOMEM:
raise getTransportTooManyError(ecode)
else:
raise getTransportOsError(ecode)
else:
case ecode
of WSAECONNABORTED, WSAENETDOWN, WSAENETRESET, WSAECONNRESET, WSAETIMEDOUT:
raise getConnectionAbortedError(ecode)
of ERROR_TOO_MANY_OPEN_FILES, WSAENOBUFS, WSAEMFILE:
raise getTransportTooManyError(ecode)
else:
raise getTransportOsError(ecode)

View File

@ -141,30 +141,28 @@ type
# transport for new client
proc remoteAddress*(transp: StreamTransport): TransportAddress {.
raises: [TransportError].} =
raises: [TransportAbortedError, TransportTooManyError, TransportOsError].} =
## Returns ``transp`` remote socket address.
if transp.kind != TransportKind.Socket:
raise newException(TransportError, "Socket required!")
doAssert(transp.kind == TransportKind.Socket, "Socket transport required!")
if transp.remote.family == AddressFamily.None:
var saddr: Sockaddr_storage
var slen = SockLen(sizeof(saddr))
if getpeername(SocketHandle(transp.fd), cast[ptr SockAddr](addr saddr),
addr slen) != 0:
raiseTransportOsError(osLastError())
raiseTransportError(osLastError())
fromSAddr(addr saddr, slen, transp.remote)
transp.remote
proc localAddress*(transp: StreamTransport): TransportAddress {.
raises: [TransportError].} =
raises: [TransportAbortedError, TransportTooManyError, TransportOsError].} =
## Returns ``transp`` local socket address.
if transp.kind != TransportKind.Socket:
raise newException(TransportError, "Socket required!")
doAssert(transp.kind == TransportKind.Socket, "Socket transport required!")
if transp.local.family == AddressFamily.None:
var saddr: Sockaddr_storage
var slen = SockLen(sizeof(saddr))
if getsockname(SocketHandle(transp.fd), cast[ptr SockAddr](addr saddr),
addr slen) != 0:
raiseTransportOsError(osLastError())
raiseTransportError(osLastError())
fromSAddr(addr saddr, slen, transp.local)
transp.local