summary refs log tree commit diff stats
path: root/lib/pure/asyncnet.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pure/asyncnet.nim')
-rw-r--r--lib/pure/asyncnet.nim220
1 files changed, 117 insertions, 103 deletions
diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim
index 455efe1c1..ee07e599e 100644
--- a/lib/pure/asyncnet.nim
+++ b/lib/pure/asyncnet.nim
@@ -8,27 +8,27 @@
 #
 
 ## This module implements a high-level asynchronous sockets API based on the
-## asynchronous dispatcher defined in the ``asyncdispatch`` module.
+## asynchronous dispatcher defined in the `asyncdispatch` module.
 ##
 ## Asynchronous IO in Nim
 ## ======================
 ##
 ## Async IO in Nim consists of multiple layers (from highest to lowest):
 ##
-## * ``asyncnet`` module
+## * `asyncnet` module
 ##
 ## * Async await
 ##
-## * ``asyncdispatch`` module (event loop)
+## * `asyncdispatch` module (event loop)
 ##
-## * ``selectors`` module
+## * `selectors` module
 ##
 ## Each builds on top of the layers below it. The selectors module is an
-## abstraction for the various system ``select()`` mechanisms such as epoll or
+## abstraction for the various system `select()` mechanisms such as epoll or
 ## kqueue. If you wish you can use it directly, and some people have done so
 ## `successfully <http://goran.krampe.se/2014/10/25/nim-socketserver/>`_.
 ## But you must be aware that on Windows it only supports
-## ``select()``.
+## `select()`.
 ##
 ## The async dispatcher implements the proactor pattern and also has an
 ## implementation of IOCP. It implements the proactor pattern for other
@@ -45,16 +45,16 @@
 ## layers interchangeably (as long as you only care about non-Windows
 ## platforms).
 ##
-## For most applications using ``asyncnet`` is the way to go as it builds
+## For most applications using `asyncnet` is the way to go as it builds
 ## over all the layers, providing some extra features such as buffering.
 ##
 ## SSL
 ## ===
 ##
-## SSL can be enabled by compiling with the ``-d:ssl`` flag.
+## SSL can be enabled by compiling with the `-d:ssl` flag.
 ##
-## You must create a new SSL context with the ``newContext`` function defined
-## in the ``net`` module. You may then call ``wrapSocket`` on your socket using
+## You must create a new SSL context with the `newContext` function defined
+## in the `net` module. You may then call `wrapSocket` on your socket using
 ## the newly created SSL context to get an SSL socket.
 ##
 ## Examples
@@ -65,9 +65,8 @@
 ##
 ## The following example demonstrates a simple chat server.
 ##
-## .. code-block::nim
-##
-##   import asyncnet, asyncdispatch
+##   ```Nim
+##   import std/[asyncnet, asyncdispatch]
 ##
 ##   var clients {.threadvar.}: seq[AsyncSocket]
 ##
@@ -93,19 +92,25 @@
 ##
 ##   asyncCheck serve()
 ##   runForever()
-##
+##   ```
 
 import std/private/since
-import asyncdispatch, nativesockets, net, os
+
+when defined(nimPreviewSlimSystem):
+  import std/[assertions, syncio]
+
+import std/[asyncdispatch, nativesockets, net, os]
 
 export SOBool
 
 # TODO: Remove duplication introduced by PR #4683.
 
 const defineSsl = defined(ssl) or defined(nimdoc)
+const useNimNetLite = defined(nimNetLite) or defined(freertos) or defined(zephyr) or
+    defined(nuttx)
 
 when defineSsl:
-  import openssl
+  import std/openssl
 
 type
   # TODO: I would prefer to just do:
@@ -134,16 +139,16 @@ proc newAsyncSocket*(fd: AsyncFD, domain: Domain = AF_INET,
                      protocol: Protocol = IPPROTO_TCP,
                      buffered = true,
                      inheritable = defined(nimInheritHandles)): owned(AsyncSocket) =
-  ## Creates a new ``AsyncSocket`` based on the supplied params.
+  ## Creates a new `AsyncSocket` based on the supplied params.
   ##
-  ## The supplied ``fd``'s non-blocking state will be enabled implicitly.
+  ## The supplied `fd`'s non-blocking state will be enabled implicitly.
   ##
-  ## If ``inheritable`` is false (the default), the supplied ``fd`` will not
+  ## If `inheritable` is false (the default), the supplied `fd` will not
   ## be inheritable by child processes.
   ##
-  ## **Note**: This procedure will **NOT** register ``fd`` with the global
+  ## **Note**: This procedure will **NOT** register `fd` with the global
   ## async dispatcher. You need to do this manually. If you have used
-  ## ``newAsyncNativeSocket`` to create ``fd`` then it's already registered.
+  ## `newAsyncNativeSocket` to create `fd` then it's already registered.
   assert fd != osInvalidSocket.AsyncFD
   new(result)
   result.fd = fd.SocketHandle
@@ -165,7 +170,7 @@ proc newAsyncSocket*(domain: Domain = AF_INET, sockType: SockType = SOCK_STREAM,
   ## This procedure will also create a brand new file descriptor for
   ## this socket.
   ##
-  ## If ``inheritable`` is false (the default), the new file descriptor will not
+  ## If `inheritable` is false (the default), the new file descriptor will not
   ## be inheritable by child processes.
   let fd = createAsyncNativeSocket(domain, sockType, protocol, inheritable)
   if fd.SocketHandle == osInvalidSocket:
@@ -178,11 +183,12 @@ proc getLocalAddr*(socket: AsyncSocket): (string, Port) =
   ## This is high-level interface for `getsockname`:idx:.
   getLocalAddr(socket.fd, socket.domain)
 
-proc getPeerAddr*(socket: AsyncSocket): (string, Port) =
-  ## Get the socket's peer address and port number.
-  ##
-  ## This is high-level interface for `getpeername`:idx:.
-  getPeerAddr(socket.fd, socket.domain)
+when not useNimNetLite:
+  proc getPeerAddr*(socket: AsyncSocket): (string, Port) =
+    ## Get the socket's peer address and port number.
+    ##
+    ## This is high-level interface for `getpeername`:idx:.
+    getPeerAddr(socket.fd, socket.domain)
 
 proc newAsyncSocket*(domain, sockType, protocol: cint,
                      buffered = true,
@@ -192,7 +198,7 @@ proc newAsyncSocket*(domain, sockType, protocol: cint,
   ## This procedure will also create a brand new file descriptor for
   ## this socket.
   ##
-  ## If ``inheritable`` is false (the default), the new file descriptor will not
+  ## If `inheritable` is false (the default), the new file descriptor will not
   ## be inheritable by child processes.
   let fd = createAsyncNativeSocket(domain, sockType, protocol, inheritable)
   if fd.SocketHandle == osInvalidSocket:
@@ -224,7 +230,7 @@ when defineSsl:
     let len = bioCtrlPending(socket.bioOut)
     if len > 0:
       var data = newString(len)
-      let read = bioRead(socket.bioOut, addr data[0], len)
+      let read = bioRead(socket.bioOut, cast[cstring](addr data[0]), len)
       assert read != 0
       if read < 0:
         raiseSSLError()
@@ -233,7 +239,7 @@ when defineSsl:
 
   proc appeaseSsl(socket: AsyncSocket, flags: set[SocketFlag],
                   sslError: cint): owned(Future[bool]) {.async.} =
-    ## Returns ``true`` if ``socket`` is still connected, otherwise ``false``.
+    ## Returns `true` if `socket` is still connected, otherwise `false`.
     result = true
     case sslError
     of SSL_ERROR_WANT_WRITE:
@@ -242,7 +248,7 @@ when defineSsl:
       var data = await recv(socket.fd.AsyncFD, BufferSize, flags)
       let length = len(data)
       if length > 0:
-        let ret = bioWrite(socket.bioIn, addr data[0], length.cint)
+        let ret = bioWrite(socket.bioIn, cast[cstring](addr data[0]), length.cint)
         if ret < 0:
           raiseSSLError()
       elif length == 0:
@@ -259,16 +265,17 @@ when defineSsl:
       ErrClearError()
       # Call the desired operation.
       opResult = op
-      # Bit hackish here.
-      # TODO: Introduce an async template transformation pragma?
-
+      let err =
+        if opResult < 0:
+          getSslError(socket, opResult.cint)
+        else:
+          SSL_ERROR_NONE
       # Send any remaining pending SSL data.
-      yield sendPendingSslData(socket, flags)
+      await sendPendingSslData(socket, flags)
 
       # If the operation failed, try to see if SSL has some data to read
       # or write.
       if opResult < 0:
-        let err = getSslError(socket, opResult.cint)
         let fut = appeaseSsl(socket, flags, err.cint)
         yield fut
         if not fut.read():
@@ -281,9 +288,9 @@ when defineSsl:
 
 proc dial*(address: string, port: Port, protocol = IPPROTO_TCP,
            buffered = true): owned(Future[AsyncSocket]) {.async.} =
-  ## Establishes connection to the specified ``address``:``port`` pair via the
+  ## Establishes connection to the specified `address`:`port` pair via the
   ## specified protocol. The procedure iterates through possible
-  ## resolutions of the ``address`` until it succeeds, meaning that it
+  ## resolutions of the `address` until it succeeds, meaning that it
   ## seamlessly works with both IPv4 and IPv6.
   ## Returns AsyncSocket ready to send or receive data.
   let asyncFd = await asyncdispatch.dial(address, port, protocol)
@@ -292,9 +299,9 @@ proc dial*(address: string, port: Port, protocol = IPPROTO_TCP,
   result = newAsyncSocket(asyncFd, domain, sockType, protocol, buffered)
 
 proc connect*(socket: AsyncSocket, address: string, port: Port) {.async.} =
-  ## Connects ``socket`` to server at ``address:port``.
+  ## Connects `socket` to server at `address:port`.
   ##
-  ## Returns a ``Future`` which will complete when the connection succeeds
+  ## Returns a `Future` which will complete when the connection succeeds
   ## or an error occurs.
   await connect(socket.fd.AsyncFD, address, port, socket.domain)
   if socket.isSsl:
@@ -310,7 +317,7 @@ proc connect*(socket: AsyncSocket, address: string, port: Port) {.async.} =
 
 template readInto(buf: pointer, size: int, socket: AsyncSocket,
                   flags: set[SocketFlag]): int =
-  ## Reads **up to** ``size`` bytes from ``socket`` into ``buf``. Note that
+  ## Reads **up to** `size` bytes from `socket` into `buf`. Note that
   ## this is a template and not a proc.
   assert(not socket.closed, "Cannot `recv` on a closed socket")
   var res = 0
@@ -321,10 +328,8 @@ template readInto(buf: pointer, size: int, socket: AsyncSocket,
         sslRead(socket.sslHandle, cast[cstring](buf), size.cint))
       res = opResult
   else:
-    var recvIntoFut = asyncdispatch.recvInto(socket.fd.AsyncFD, buf, size, flags)
-    yield recvIntoFut
     # Not in SSL mode.
-    res = recvIntoFut.read()
+    res = await asyncdispatch.recvInto(socket.fd.AsyncFD, buf, size, flags)
   res
 
 template readIntoBuf(socket: AsyncSocket,
@@ -336,10 +341,10 @@ template readIntoBuf(socket: AsyncSocket,
 
 proc recvInto*(socket: AsyncSocket, buf: pointer, size: int,
            flags = {SocketFlag.SafeDisconn}): owned(Future[int]) {.async.} =
-  ## Reads **up to** ``size`` bytes from ``socket`` into ``buf``.
+  ## Reads **up to** `size` bytes from `socket` into `buf`.
   ##
   ## For buffered sockets this function will attempt to read all the requested
-  ## data. It will read this data in ``BufferSize`` chunks.
+  ## data. It will read this data in `BufferSize` chunks.
   ##
   ## For unbuffered sockets this function makes no effort to read
   ## all the data requested. It will return as much data as the operating system
@@ -350,7 +355,7 @@ proc recvInto*(socket: AsyncSocket, buf: pointer, size: int,
   ## requested data.
   ##
   ## If socket is disconnected and no data is available
-  ## to be read then the future will complete with a value of ``0``.
+  ## to be read then the future will complete with a value of `0`.
   if socket.isBuffered:
     let originalBufPos = socket.currPos
 
@@ -384,10 +389,10 @@ proc recvInto*(socket: AsyncSocket, buf: pointer, size: int,
 
 proc recv*(socket: AsyncSocket, size: int,
            flags = {SocketFlag.SafeDisconn}): owned(Future[string]) {.async.} =
-  ## Reads **up to** ``size`` bytes from ``socket``.
+  ## Reads **up to** `size` bytes from `socket`.
   ##
   ## For buffered sockets this function will attempt to read all the requested
-  ## data. It will read this data in ``BufferSize`` chunks.
+  ## data. It will read this data in `BufferSize` chunks.
   ##
   ## For unbuffered sockets this function makes no effort to read
   ## all the data requested. It will return as much data as the operating system
@@ -398,10 +403,11 @@ proc recv*(socket: AsyncSocket, size: int,
   ## requested data.
   ##
   ## If socket is disconnected and no data is available
-  ## to be read then the future will complete with a value of ``""``.
+  ## to be read then the future will complete with a value of `""`.
   if socket.isBuffered:
     result = newString(size)
-    shallow(result)
+    when not defined(nimSeqsV2):
+      shallow(result)
     let originalBufPos = socket.currPos
 
     if socket.bufLen == 0:
@@ -436,7 +442,7 @@ proc recv*(socket: AsyncSocket, size: int,
 
 proc send*(socket: AsyncSocket, buf: pointer, size: int,
             flags = {SocketFlag.SafeDisconn}) {.async.} =
-  ## Sends ``size`` bytes from ``buf`` to ``socket``. The returned future will complete once all
+  ## Sends `size` bytes from `buf` to `socket`. The returned future will complete once all
   ## data has been sent.
   assert socket != nil
   assert(not socket.closed, "Cannot `send` on a closed socket")
@@ -450,14 +456,14 @@ proc send*(socket: AsyncSocket, buf: pointer, size: int,
 
 proc send*(socket: AsyncSocket, data: string,
            flags = {SocketFlag.SafeDisconn}) {.async.} =
-  ## Sends ``data`` to ``socket``. The returned future will complete once all
+  ## Sends `data` to `socket`. The returned future will complete once all
   ## data has been sent.
   assert socket != nil
   if socket.isSsl:
     when defineSsl:
       var copy = data
       sslLoop(socket, flags,
-        sslWrite(socket.sslHandle, addr copy[0], copy.len.cint))
+        sslWrite(socket.sslHandle, cast[cstring](addr copy[0]), copy.len.cint))
       await sendPendingSslData(socket, flags)
   else:
     await send(socket.fd.AsyncFD, data, flags)
@@ -468,7 +474,7 @@ proc acceptAddr*(socket: AsyncSocket, flags = {SocketFlag.SafeDisconn},
   ## Accepts a new connection. Returns a future containing the client socket
   ## corresponding to that connection and the remote address of the client.
   ##
-  ## If ``inheritable`` is false (the default), the resulting client socket will
+  ## If `inheritable` is false (the default), the resulting client socket will
   ## not be inheritable by child processes.
   ##
   ## The future will complete when the connection is successfully accepted.
@@ -490,7 +496,7 @@ proc accept*(socket: AsyncSocket,
     flags = {SocketFlag.SafeDisconn}): owned(Future[AsyncSocket]) =
   ## Accepts a new connection. Returns a future containing the client socket
   ## corresponding to that connection.
-  ## If ``inheritable`` is false (the default), the resulting client socket will
+  ## If `inheritable` is false (the default), the resulting client socket will
   ## not be inheritable by child processes.
   ## The future will complete when the connection is successfully accepted.
   var retFut = newFuture[AsyncSocket]("asyncnet.accept")
@@ -506,25 +512,24 @@ proc accept*(socket: AsyncSocket,
 
 proc recvLineInto*(socket: AsyncSocket, resString: FutureVar[string],
     flags = {SocketFlag.SafeDisconn}, maxLength = MaxLineLength) {.async.} =
-  ## Reads a line of data from ``socket`` into ``resString``.
+  ## Reads a line of data from `socket` into `resString`.
   ##
-  ## If a full line is read ``\r\L`` is not
-  ## added to ``line``, however if solely ``\r\L`` is read then ``line``
+  ## If a full line is read `\r\L` is not
+  ## added to `line`, however if solely `\r\L` is read then `line`
   ## will be set to it.
   ##
-  ## If the socket is disconnected, ``line`` will be set to ``""``.
+  ## If the socket is disconnected, `line` will be set to `""`.
   ##
-  ## If the socket is disconnected in the middle of a line (before ``\r\L``
-  ## is read) then line will be set to ``""``.
+  ## If the socket is disconnected in the middle of a line (before `\r\L`
+  ## is read) then line will be set to `""`.
   ## The partial line **will be lost**.
   ##
-  ## The ``maxLength`` parameter determines the maximum amount of characters
-  ## that can be read. ``resString`` will be truncated after that.
+  ## The `maxLength` parameter determines the maximum amount of characters
+  ## that can be read. `resString` will be truncated after that.
   ##
-  ## **Warning**: The ``Peek`` flag is not yet implemented.
+  ## .. warning:: The `Peek` flag is not yet implemented.
   ##
-  ## **Warning**: ``recvLineInto`` on unbuffered sockets assumes that the
-  ## protocol uses ``\r\L`` to delimit a new line.
+  ## .. warning:: `recvLineInto` on unbuffered sockets assumes that the protocol uses `\r\L` to delimit a new line.
   assert SocketFlag.Peek notin flags ## TODO:
   result = newFuture[void]("asyncnet.recvLineInto")
 
@@ -599,26 +604,25 @@ proc recvLineInto*(socket: AsyncSocket, resString: FutureVar[string],
 proc recvLine*(socket: AsyncSocket,
     flags = {SocketFlag.SafeDisconn},
     maxLength = MaxLineLength): owned(Future[string]) {.async.} =
-  ## Reads a line of data from ``socket``. Returned future will complete once
+  ## Reads a line of data from `socket`. Returned future will complete once
   ## a full line is read or an error occurs.
   ##
-  ## If a full line is read ``\r\L`` is not
-  ## added to ``line``, however if solely ``\r\L`` is read then ``line``
+  ## If a full line is read `\r\L` is not
+  ## added to `line`, however if solely `\r\L` is read then `line`
   ## will be set to it.
   ##
-  ## If the socket is disconnected, ``line`` will be set to ``""``.
+  ## If the socket is disconnected, `line` will be set to `""`.
   ##
-  ## If the socket is disconnected in the middle of a line (before ``\r\L``
-  ## is read) then line will be set to ``""``.
+  ## If the socket is disconnected in the middle of a line (before `\r\L`
+  ## is read) then line will be set to `""`.
   ## The partial line **will be lost**.
   ##
-  ## The ``maxLength`` parameter determines the maximum amount of characters
+  ## The `maxLength` parameter determines the maximum amount of characters
   ## that can be read. The result is truncated after that.
   ##
-  ## **Warning**: The ``Peek`` flag is not yet implemented.
+  ## .. warning:: The `Peek` flag is not yet implemented.
   ##
-  ## **Warning**: ``recvLine`` on unbuffered sockets assumes that the protocol
-  ## uses ``\r\L`` to delimit a new line.
+  ## .. warning:: `recvLine` on unbuffered sockets assumes that the protocol uses `\r\L` to delimit a new line.
   assert SocketFlag.Peek notin flags ## TODO:
 
   # TODO: Optimise this
@@ -629,8 +633,8 @@ proc recvLine*(socket: AsyncSocket,
 
 proc listen*(socket: AsyncSocket, backlog = SOMAXCONN) {.tags: [
     ReadIOEffect].} =
-  ## Marks ``socket`` as accepting connections.
-  ## ``Backlog`` specifies the maximum length of the
+  ## Marks `socket` as accepting connections.
+  ## `Backlog` specifies the maximum length of the
   ## queue of pending connections.
   ##
   ## Raises an OSError error upon failure.
@@ -638,9 +642,9 @@ proc listen*(socket: AsyncSocket, backlog = SOMAXCONN) {.tags: [
 
 proc bindAddr*(socket: AsyncSocket, port = Port(0), address = "") {.
   tags: [ReadIOEffect].} =
-  ## Binds ``address``:``port`` to the socket.
+  ## Binds `address`:`port` to the socket.
   ##
-  ## If ``address`` is "" then ADDR_ANY will be bound.
+  ## If `address` is "" then ADDR_ANY will be bound.
   var realaddr = address
   if realaddr == "":
     case socket.domain
@@ -652,11 +656,16 @@ proc bindAddr*(socket: AsyncSocket, port = Port(0), address = "") {.
 
   var aiList = getAddrInfo(realaddr, port, socket.domain)
   if bindAddr(socket.fd, aiList.ai_addr, aiList.ai_addrlen.SockLen) < 0'i32:
-    freeaddrinfo(aiList)
+    freeAddrInfo(aiList)
     raiseOSError(osLastError())
-  freeaddrinfo(aiList)
+  freeAddrInfo(aiList)
+
+proc hasDataBuffered*(s: AsyncSocket): bool {.since: (1, 5).} =
+  ## Determines whether an AsyncSocket has data buffered.
+  # xxx dedup with std/net
+  s.isBuffered and s.bufLen > 0 and s.currPos != s.bufLen
 
-when defined(posix):
+when defined(posix) and not useNimNetLite:
 
   proc connectUnix*(socket: AsyncSocket, path: string): owned(Future[void]) =
     ## Binds Unix socket to `path`.
@@ -673,12 +682,12 @@ when defined(posix):
         elif ret == EINTR:
           return false
         else:
-          retFuture.fail(newException(OSError, osErrorMsg(OSErrorCode(ret))))
+          retFuture.fail(newOSError(OSErrorCode(ret)))
           return true
 
       var socketAddr = makeUnixAddr(path)
       let ret = socket.fd.connect(cast[ptr SockAddr](addr socketAddr),
-                        (sizeof(socketAddr.sun_family) + path.len).SockLen)
+                        (offsetOf(socketAddr, sun_path) + path.len + 1).SockLen)
       if ret == 0:
         # Request to connect completed immediately.
         retFuture.complete()
@@ -687,7 +696,7 @@ when defined(posix):
         if lastError.int32 == EINTR or lastError.int32 == EINPROGRESS:
           addWrite(AsyncFD(socket.fd), cb)
         else:
-          retFuture.fail(newException(OSError, osErrorMsg(lastError)))
+          retFuture.fail(newOSError(lastError))
 
   proc bindUnix*(socket: AsyncSocket, path: string) {.
     tags: [ReadIOEffect].} =
@@ -696,7 +705,7 @@ when defined(posix):
     when not defined(nimdoc):
       var socketAddr = makeUnixAddr(path)
       if socket.fd.bindAddr(cast[ptr SockAddr](addr socketAddr),
-          (sizeof(socketAddr.sun_family) + path.len).SockLen) != 0'i32:
+          (offsetOf(socketAddr, sun_path) + path.len + 1).SockLen) != 0'i32:
         raiseOSError(osLastError())
 
 elif defined(nimdoc):
@@ -737,9 +746,14 @@ proc close*(socket: AsyncSocket) =
         raiseSSLError()
 
 when defineSsl:
+  proc sslHandle*(self: AsyncSocket): SslPtr =
+    ## Retrieve the ssl pointer of `socket`.
+    ## Useful for interfacing with `openssl`.
+    self.sslHandle
+  
   proc wrapSocket*(ctx: SslContext, socket: AsyncSocket) =
     ## Wraps a socket in an SSL context. This function effectively turns
-    ## ``socket`` into an SSL socket.
+    ## `socket` into an SSL socket.
     ##
     ## **Disclaimer**: This code is not well tested, may be very unsafe and
     ## prone to security vulnerabilities.
@@ -759,8 +773,8 @@ when defineSsl:
                             handshake: SslHandshakeType,
                             hostname: string = "") =
     ## Wraps a connected socket in an SSL context. This function effectively
-    ## turns ``socket`` into an SSL socket.
-    ## ``hostname`` should be specified so that the client knows which hostname
+    ## turns `socket` into an SSL socket.
+    ## `hostname` should be specified so that the client knows which hostname
     ## the server certificate should be validated against.
     ##
     ## This should be called on a connected socket, and will perform
@@ -793,18 +807,18 @@ when defineSsl:
 
 proc getSockOpt*(socket: AsyncSocket, opt: SOBool, level = SOL_SOCKET): bool {.
   tags: [ReadIOEffect].} =
-  ## Retrieves option ``opt`` as a boolean value.
+  ## Retrieves option `opt` as a boolean value.
   var res = getSockOptInt(socket.fd, cint(level), toCInt(opt))
   result = res != 0
 
 proc setSockOpt*(socket: AsyncSocket, opt: SOBool, value: bool,
     level = SOL_SOCKET) {.tags: [WriteIOEffect].} =
-  ## Sets option ``opt`` to a boolean value specified by ``value``.
+  ## Sets option `opt` to a boolean value specified by `value`.
   var valuei = cint(if value: 1 else: 0)
   setSockOptInt(socket.fd, cint(level), toCInt(opt), valuei)
 
 proc isSsl*(socket: AsyncSocket): bool =
-  ## Determines whether ``socket`` is a SSL socket.
+  ## Determines whether `socket` is a SSL socket.
   socket.isSsl
 
 proc getFd*(socket: AsyncSocket): SocketHandle =
@@ -818,7 +832,7 @@ proc isClosed*(socket: AsyncSocket): bool =
 proc sendTo*(socket: AsyncSocket, address: string, port: Port, data: string,
              flags = {SocketFlag.SafeDisconn}): owned(Future[void])
             {.async, since: (1, 3).} =
-  ## This proc sends ``data`` to the specified ``address``, which may be an IP
+  ## This proc sends `data` to the specified `address`, which may be an IP
   ## address or a hostname. If a hostname is specified this function will try
   ## each IP of that hostname. The returned future will complete once all data
   ## has been sent.
@@ -853,7 +867,7 @@ proc sendTo*(socket: AsyncSocket, address: string, port: Port, data: string,
 
     it = it.ai_next
 
-  freeaddrinfo(aiList)
+  freeAddrInfo(aiList)
 
   if not success:
     if lastException != nil:
@@ -865,9 +879,9 @@ proc recvFrom*(socket: AsyncSocket, data: FutureVar[string], size: int,
                address: FutureVar[string], port: FutureVar[Port],
                flags = {SocketFlag.SafeDisconn}): owned(Future[int])
               {.async, since: (1, 3).} =
-  ## Receives a datagram data from ``socket`` into ``data``, which must be at
-  ## least of size ``size``. The address and port of datagram's sender will be
-  ## stored into ``address`` and ``port``, respectively. Returned future will
+  ## Receives a datagram data from `socket` into `data`, which must be at
+  ## least of size `size`. The address and port of datagram's sender will be
+  ## stored into `address` and `port`, respectively. Returned future will
   ## complete once one datagram has been received, and will return size of
   ## packet received.
   ##
@@ -876,8 +890,8 @@ proc recvFrom*(socket: AsyncSocket, data: FutureVar[string], size: int,
   ## This proc is normally used with connectionless sockets (UDP sockets).
   ##
   ## **Notes**
-  ## * ``data`` must be initialized to the length of ``size``.
-  ## * ``address`` must be initialized to 46 in length.
+  ## * `data` must be initialized to the length of `size`.
+  ## * `address` must be initialized to 46 in length.
   template adaptRecvFromToDomain(domain: Domain) =
     var lAddr = sizeof(sAddr).SockLen
 
@@ -919,8 +933,8 @@ proc recvFrom*(socket: AsyncSocket, size: int,
                flags = {SocketFlag.SafeDisconn}):
               owned(Future[tuple[data: string, address: string, port: Port]])
               {.async, since: (1, 3).} =
-  ## Receives a datagram data from ``socket``, which must be at least of size
-  ## ``size``. Returned future will complete once one datagram has been received
+  ## Receives a datagram data from `socket`, which must be at least of size
+  ## `size`. Returned future will complete once one datagram has been received
   ## and will return tuple with: data of packet received; and address and port
   ## of datagram's sender.
   ##