Merge pull request #2279 from nathan-hoad/sni-support-for-openssl
Add SNI support to client and server sockets.
This commit is contained in:
commit
3ea3aa633d
3 changed files with 122 additions and 18 deletions
|
|
@ -81,6 +81,23 @@ type
|
|||
TReadLineResult: ReadLineResult, TSOBool: SOBool, PSocket: Socket,
|
||||
TSocketImpl: SocketImpl].}
|
||||
|
||||
type
|
||||
IpAddressFamily* {.pure.} = enum ## Describes the type of an IP address
|
||||
IPv6, ## IPv6 address
|
||||
IPv4 ## IPv4 address
|
||||
|
||||
TIpAddress* = object ## stores an arbitrary IP address
|
||||
case family*: IpAddressFamily ## the type of the IP address (IPv4 or IPv6)
|
||||
of IpAddressFamily.IPv6:
|
||||
address_v6*: array[0..15, uint8] ## Contains the IP address in bytes in
|
||||
## case of IPv6
|
||||
of IpAddressFamily.IPv4:
|
||||
address_v4*: array[0..3, uint8] ## Contains the IP address in bytes in
|
||||
## case of IPv4
|
||||
|
||||
proc isIpAddress*(address_str: string): bool {.tags: [].}
|
||||
proc parseIpAddress*(address_str: string): TIpAddress
|
||||
|
||||
proc isDisconnectionError*(flags: set[SocketFlag],
|
||||
lastError: OSErrorCode): bool =
|
||||
## Determines whether ``lastError`` is a disconnection error. Only does this
|
||||
|
|
@ -511,6 +528,12 @@ proc connect*(socket: Socket, address: string, port = Port(0),
|
|||
|
||||
when defined(ssl):
|
||||
if socket.isSSL:
|
||||
# RFC3546 for SNI specifies that IP addresses are not allowed.
|
||||
if not isIpAddress(address):
|
||||
# Discard result in case OpenSSL version doesn't support SNI, or we're
|
||||
# not using TLSv1+
|
||||
discard SSL_set_tlsext_host_name(socket.sslHandle, address)
|
||||
|
||||
let ret = SSLConnect(socket.sslHandle)
|
||||
socketError(socket, ret)
|
||||
|
||||
|
|
@ -969,20 +992,6 @@ proc isSsl*(socket: Socket): bool =
|
|||
proc getFd*(socket: Socket): SocketHandle = return socket.fd
|
||||
## Returns the socket's file descriptor
|
||||
|
||||
type
|
||||
IpAddressFamily* {.pure.} = enum ## Describes the type of an IP address
|
||||
IPv6, ## IPv6 address
|
||||
IPv4 ## IPv4 address
|
||||
|
||||
TIpAddress* = object ## stores an arbitrary IP address
|
||||
case family*: IpAddressFamily ## the type of the IP address (IPv4 or IPv6)
|
||||
of IpAddressFamily.IPv6:
|
||||
address_v6*: array[0..15, uint8] ## Contains the IP address in bytes in
|
||||
## case of IPv6
|
||||
of IpAddressFamily.IPv4:
|
||||
address_v4*: array[0..3, uint8] ## Contains the IP address in bytes in
|
||||
## case of IPv4
|
||||
|
||||
proc IPv4_any*(): TIpAddress =
|
||||
## Returns the IPv4 any address, which can be used to listen on all available
|
||||
## network adapters
|
||||
|
|
@ -1241,7 +1250,7 @@ proc parseIPv6Address(address_str: string): TIpAddress =
|
|||
raise newException(ValueError,
|
||||
"Invalid IP Address. The address consists of too many groups")
|
||||
|
||||
proc parseIpAddress*(address_str: string): TIpAddress =
|
||||
proc parseIpAddress(address_str: string): TIpAddress =
|
||||
## Parses an IP address
|
||||
## Raises EInvalidValue on error
|
||||
if address_str == nil:
|
||||
|
|
@ -1250,3 +1259,13 @@ proc parseIpAddress*(address_str: string): TIpAddress =
|
|||
return parseIPv6Address(address_str)
|
||||
else:
|
||||
return parseIPv4Address(address_str)
|
||||
|
||||
|
||||
proc isIpAddress(address_str: string): bool =
|
||||
## Checks if a string is an IP address
|
||||
## Returns true if it is, false otherwise
|
||||
try:
|
||||
discard parseIpAddress(address_str)
|
||||
except ValueError:
|
||||
return false
|
||||
return true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue