summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/asyncdispatch.nim7
-rw-r--r--lib/pure/asyncnet.nim14
-rw-r--r--lib/pure/ioselects/ioselectors_epoll.nim5
-rw-r--r--lib/pure/ioselects/ioselectors_poll.nim5
-rw-r--r--lib/pure/ioselects/ioselectors_select.nim2
-rw-r--r--lib/pure/nativesockets.nim605
-rw-r--r--lib/pure/net.nim17
-rw-r--r--lib/pure/selectors.nim19
8 files changed, 388 insertions, 286 deletions
diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim
index d87e2360f..e15fb0851 100644
--- a/lib/pure/asyncdispatch.nim
+++ b/lib/pure/asyncdispatch.nim
@@ -1973,15 +1973,18 @@ proc activeDescriptors*(): int {.inline.} =
 when defined(posix):
   import posix
 
-when defined(linux) or defined(windows) or defined(macosx) or defined(bsd):
+when defined(linux) or defined(windows) or defined(macosx) or defined(bsd) or
+       defined(zephyr) or defined(freertos):
   proc maxDescriptors*(): int {.raises: OSError.} =
     ## Returns the maximum number of active file descriptors for the current
     ## process. This involves a system call. For now `maxDescriptors` is
     ## supported on the following OSes: Windows, Linux, OSX, BSD.
     when defined(windows):
       result = 16_700_000
+    elif defined(zephyr) or defined(freertos):
+      result = FD_MAX
     else:
       var fdLim: RLimit
       if getrlimit(RLIMIT_NOFILE, fdLim) < 0:
         raiseOSError(osLastError())
-      result = int(fdLim.rlim_cur) - 1
+      result = int(fdLim.rlim_cur) - 1
\ No newline at end of file
diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim
index 5523fa10e..abb4dd075 100644
--- a/lib/pure/asyncnet.nim
+++ b/lib/pure/asyncnet.nim
@@ -103,6 +103,7 @@ 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)
 
 when defineSsl:
   import openssl
@@ -178,11 +179,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,
@@ -655,7 +657,7 @@ proc hasDataBuffered*(s: AsyncSocket): bool {.since: (1, 5).} =
   # 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`.
diff --git a/lib/pure/ioselects/ioselectors_epoll.nim b/lib/pure/ioselects/ioselectors_epoll.nim
index b62b4c2db..05d9d19a8 100644
--- a/lib/pure/ioselects/ioselectors_epoll.nim
+++ b/lib/pure/ioselects/ioselectors_epoll.nim
@@ -73,10 +73,7 @@ type
 
 proc newSelector*[T](): Selector[T] =
   # Retrieve the maximum fd count (for current OS) via getrlimit()
-  var a = RLimit()
-  if getrlimit(posix.RLIMIT_NOFILE, a) != 0:
-    raiseOSError(osLastError())
-  var maxFD = int(a.rlim_max)
+  var maxFD = maxDescriptors()
   doAssert(maxFD > 0)
   # Start with a reasonable size, checkFd() will grow this on demand
   const numFD = 1024
diff --git a/lib/pure/ioselects/ioselectors_poll.nim b/lib/pure/ioselects/ioselectors_poll.nim
index 6b10e19ae..0d8fef78a 100644
--- a/lib/pure/ioselects/ioselectors_poll.nim
+++ b/lib/pure/ioselects/ioselectors_poll.nim
@@ -53,10 +53,7 @@ else:
     body
 
 proc newSelector*[T](): Selector[T] =
-  var a = RLimit()
-  if getrlimit(posix.RLIMIT_NOFILE, a) != 0:
-    raiseIOSelectorsError(osLastError())
-  var maxFD = int(a.rlim_max)
+  var maxFD = maxDescriptors()
 
   when hasThreadSupport:
     result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T])))
diff --git a/lib/pure/ioselects/ioselectors_select.nim b/lib/pure/ioselects/ioselectors_select.nim
index 6f216ac85..88cbaf28c 100644
--- a/lib/pure/ioselects/ioselectors_select.nim
+++ b/lib/pure/ioselects/ioselectors_select.nim
@@ -313,7 +313,7 @@ proc selectInto*[T](s: Selector[T], timeout: int,
   verifySelectParams(timeout)
 
   if timeout != -1:
-    when defined(genode) or defined(freertos):
+    when defined(genode) or defined(freertos) or defined(zephyr):
       tv.tv_sec = Time(timeout div 1_000)
     else:
       tv.tv_sec = timeout.int32 div 1_000
diff --git a/lib/pure/nativesockets.nim b/lib/pure/nativesockets.nim
index 13c08dd92..4037d7181 100644
--- a/lib/pure/nativesockets.nim
+++ b/lib/pure/nativesockets.nim
@@ -21,6 +21,7 @@ when hostOS == "solaris":
   {.passl: "-lsocket -lnsl".}
 
 const useWinVersion = defined(windows) or defined(nimdoc)
+const useNimNetLite = defined(nimNetLite) or defined(freertos) or defined(zephyr)
 
 when useWinVersion:
   import winlean
@@ -35,9 +36,12 @@ else:
 
 export SocketHandle, Sockaddr_in, Addrinfo, INADDR_ANY, SockAddr, SockLen,
   Sockaddr_in6, Sockaddr_storage,
-  inet_ntoa, recv, `==`, connect, send, accept, recvfrom, sendto,
+  recv, `==`, connect, send, accept, recvfrom, sendto,
   freeAddrInfo
 
+when not useNimNetLite:
+  export inet_ntoa
+
 export
   SO_ERROR,
   SOL_SOCKET,
@@ -332,125 +336,6 @@ template htons*(x: uint16): untyped =
   ## order, this is a no-op; otherwise, it performs a 2-byte swap operation.
   nativesockets.ntohs(x)
 
-proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} =
-  ## Searches the database from the beginning and finds the first entry for
-  ## which the service name specified by `name` matches the s_name member
-  ## and the protocol name specified by `proto` matches the s_proto member.
-  ##
-  ## On posix this will search through the `/etc/services` file.
-  when useWinVersion:
-    var s = winlean.getservbyname(name, proto)
-  else:
-    var s = posix.getservbyname(name, proto)
-  if s == nil: raiseOSError(osLastError(), "Service not found.")
-  result.name = $s.s_name
-  result.aliases = cstringArrayToSeq(s.s_aliases)
-  result.port = Port(s.s_port)
-  result.proto = $s.s_proto
-
-proc getServByPort*(port: Port, proto: string): Servent {.tags: [ReadIOEffect].} =
-  ## Searches the database from the beginning and finds the first entry for
-  ## which the port specified by `port` matches the s_port member and the
-  ## protocol name specified by `proto` matches the s_proto member.
-  ##
-  ## On posix this will search through the `/etc/services` file.
-  when useWinVersion:
-    var s = winlean.getservbyport(ze(int16(port)).cint, proto)
-  else:
-    var s = posix.getservbyport(ze(int16(port)).cint, proto)
-  if s == nil: raiseOSError(osLastError(), "Service not found.")
-  result.name = $s.s_name
-  result.aliases = cstringArrayToSeq(s.s_aliases)
-  result.port = Port(s.s_port)
-  result.proto = $s.s_proto
-
-proc getHostByAddr*(ip: string): Hostent {.tags: [ReadIOEffect].} =
-  ## This function will lookup the hostname of an IP Address.
-  var myaddr: InAddr
-  myaddr.s_addr = inet_addr(ip)
-
-  when useWinVersion:
-    var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr).cuint,
-                                  cint(AF_INET))
-    if s == nil: raiseOSError(osLastError())
-  else:
-    var s =
-      when defined(android4):
-        posix.gethostbyaddr(cast[cstring](addr(myaddr)), sizeof(myaddr).cint,
-                            cint(posix.AF_INET))
-      else:
-        posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).SockLen,
-                            cint(posix.AF_INET))
-    if s == nil:
-      raiseOSError(osLastError(), $hstrerror(h_errno))
-
-  result.name = $s.h_name
-  result.aliases = cstringArrayToSeq(s.h_aliases)
-  when useWinVersion:
-    result.addrtype = Domain(s.h_addrtype)
-  else:
-    if s.h_addrtype == posix.AF_INET:
-      result.addrtype = AF_INET
-    elif s.h_addrtype == posix.AF_INET6:
-      result.addrtype = AF_INET6
-    else:
-      raiseOSError(osLastError(), "unknown h_addrtype")
-  if result.addrtype == AF_INET:
-    result.addrList = @[]
-    var i = 0
-    while not isNil(s.h_addr_list[i]):
-      var inaddrPtr = cast[ptr InAddr](s.h_addr_list[i])
-      result.addrList.add($inet_ntoa(inaddrPtr[]))
-      inc(i)
-  else:
-    result.addrList = cstringArrayToSeq(s.h_addr_list)
-  result.length = int(s.h_length)
-
-proc getHostByName*(name: string): Hostent {.tags: [ReadIOEffect].} =
-  ## This function will lookup the IP address of a hostname.
-  when useWinVersion:
-    var s = winlean.gethostbyname(name)
-  else:
-    var s = posix.gethostbyname(name)
-  if s == nil: raiseOSError(osLastError())
-  result.name = $s.h_name
-  result.aliases = cstringArrayToSeq(s.h_aliases)
-  when useWinVersion:
-    result.addrtype = Domain(s.h_addrtype)
-  else:
-    if s.h_addrtype == posix.AF_INET:
-      result.addrtype = AF_INET
-    elif s.h_addrtype == posix.AF_INET6:
-      result.addrtype = AF_INET6
-    else:
-      raiseOSError(osLastError(), "unknown h_addrtype")
-  if result.addrtype == AF_INET:
-    result.addrList = @[]
-    var i = 0
-    while not isNil(s.h_addr_list[i]):
-      var inaddrPtr = cast[ptr InAddr](s.h_addr_list[i])
-      result.addrList.add($inet_ntoa(inaddrPtr[]))
-      inc(i)
-  else:
-    result.addrList = cstringArrayToSeq(s.h_addr_list)
-  result.length = int(s.h_length)
-
-proc getHostname*(): string {.tags: [ReadIOEffect].} =
-  ## Returns the local hostname (not the FQDN)
-  # https://tools.ietf.org/html/rfc1035#section-2.3.1
-  # https://tools.ietf.org/html/rfc2181#section-11
-  const size = 256
-  result = newString(size)
-  when useWinVersion:
-    let success = winlean.gethostname(result, size)
-  else:
-    # Posix
-    let success = posix.gethostname(result, size)
-  if success != 0.cint:
-    raiseOSError(osLastError())
-  let x = len(cstring(result))
-  result.setLen(x)
-
 proc getSockDomain*(socket: SocketHandle): Domain =
   ## Returns the socket's domain (AF_INET or AF_INET6).
   var name: Sockaddr_in6
@@ -464,162 +349,354 @@ proc getSockDomain*(socket: SocketHandle): Domain =
   else:
     raise newException(IOError, "Unknown socket family in getSockDomain")
 
-proc getAddrString*(sockAddr: ptr SockAddr): string =
-  ## Returns the string representation of address within sockAddr
-  if sockAddr.sa_family.cint == nativeAfInet:
-    result = $inet_ntoa(cast[ptr Sockaddr_in](sockAddr).sin_addr)
-  elif sockAddr.sa_family.cint == nativeAfInet6:
-    let addrLen = when not useWinVersion: posix.INET6_ADDRSTRLEN.int
-                  else: 46 # it's actually 46 in both cases
-    result = newString(addrLen)
-    let addr6 = addr cast[ptr Sockaddr_in6](sockAddr).sin6_addr
-    when not useWinVersion:
-      if posix.inet_ntop(posix.AF_INET6, addr6, addr result[0],
-                         result.len.int32) == nil:
-        raiseOSError(osLastError())
-      if posix.IN6_IS_ADDR_V4MAPPED(addr6) != 0:
-        result.setSlice("::ffff:".len..<addrLen)
+when not useNimNetLite: 
+  proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} =
+    ## Searches the database from the beginning and finds the first entry for
+    ## which the service name specified by `name` matches the s_name member
+    ## and the protocol name specified by `proto` matches the s_proto member.
+    ##
+    ## On posix this will search through the `/etc/services` file.
+    when useWinVersion:
+      var s = winlean.getservbyname(name, proto)
     else:
-      if winlean.inet_ntop(winlean.AF_INET6, addr6, addr result[0],
-                           result.len.int32) == nil:
-        raiseOSError(osLastError())
-    setLen(result, len(cstring(result)))
-  else:
-    when defined(posix) and not defined(nimdoc):
-      if sockAddr.sa_family.cint == nativeAfUnix:
-        return "unix"
-    raise newException(IOError, "Unknown socket family in getAddrString")
-
-proc getAddrString*(sockAddr: ptr SockAddr, strAddress: var string) =
-  ## Stores in `strAddress` the string representation of the address inside
-  ## `sockAddr`
-  ##
-  ## **Note**
-  ## * `strAddress` must be initialized to 46 in length.
-  const length = 46
-  assert(length == len(strAddress),
-         "`strAddress` was not initialized correctly. 46 != `len(strAddress)`")
-  if sockAddr.sa_family.cint == nativeAfInet:
-    let addr4 = addr cast[ptr Sockaddr_in](sockAddr).sin_addr
-    when not useWinVersion:
-      if posix.inet_ntop(posix.AF_INET, addr4, addr strAddress[0],
-                         strAddress.len.int32) == nil:
-        raiseOSError(osLastError())
+      var s = posix.getservbyname(name, proto)
+    if s == nil: raiseOSError(osLastError(), "Service not found.")
+    result.name = $s.s_name
+    result.aliases = cstringArrayToSeq(s.s_aliases)
+    result.port = Port(s.s_port)
+    result.proto = $s.s_proto
+
+  proc getServByPort*(port: Port, proto: string): Servent {.tags: [ReadIOEffect].} =
+    ## Searches the database from the beginning and finds the first entry for
+    ## which the port specified by `port` matches the s_port member and the
+    ## protocol name specified by `proto` matches the s_proto member.
+    ##
+    ## On posix this will search through the `/etc/services` file.
+    when useWinVersion:
+      var s = winlean.getservbyport(ze(int16(port)).cint, proto)
     else:
-      if winlean.inet_ntop(winlean.AF_INET, addr4, addr strAddress[0],
-                           strAddress.len.int32) == nil:
-        raiseOSError(osLastError())
-  elif sockAddr.sa_family.cint == nativeAfInet6:
-    let addr6 = addr cast[ptr Sockaddr_in6](sockAddr).sin6_addr
-    when not useWinVersion:
-      if posix.inet_ntop(posix.AF_INET6, addr6, addr strAddress[0],
-                         strAddress.len.int32) == nil:
-        raiseOSError(osLastError())
-      if posix.IN6_IS_ADDR_V4MAPPED(addr6) != 0:
-        strAddress.setSlice("::ffff:".len..<length)
+      var s = posix.getservbyport(ze(int16(port)).cint, proto)
+    if s == nil: raiseOSError(osLastError(), "Service not found.")
+    result.name = $s.s_name
+    result.aliases = cstringArrayToSeq(s.s_aliases)
+    result.port = Port(s.s_port)
+    result.proto = $s.s_proto
+
+  proc getHostByAddr*(ip: string): Hostent {.tags: [ReadIOEffect].} =
+    ## This function will lookup the hostname of an IP Address.
+    var myaddr: InAddr
+    myaddr.s_addr = inet_addr(ip)
+
+    when useWinVersion:
+      var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr).cuint,
+                                    cint(AF_INET))
+      if s == nil: raiseOSError(osLastError())
     else:
-      if winlean.inet_ntop(winlean.AF_INET6, addr6, addr strAddress[0],
-                           strAddress.len.int32) == nil:
-        raiseOSError(osLastError())
-  else:
-    raise newException(IOError, "Unknown socket family in getAddrString")
-  setLen(strAddress, len(cstring(strAddress)))
-
-when defined(posix) and not defined(nimdoc):
-  proc makeUnixAddr*(path: string): Sockaddr_un =
-    result.sun_family = AF_UNIX.TSa_Family
-    if path.len >= Sockaddr_un_path_length:
-      raise newException(ValueError, "socket path too long")
-    copyMem(addr result.sun_path, path.cstring, path.len + 1)
-
-proc getSockName*(socket: SocketHandle): Port =
-  ## Returns the socket's associated port number.
-  var name: Sockaddr_in
-  when useWinVersion:
-    name.sin_family = uint16(ord(AF_INET))
-  else:
-    name.sin_family = TSa_Family(posix.AF_INET)
-  #name.sin_port = htons(cint16(port))
-  #name.sin_addr.s_addr = htonl(INADDR_ANY)
-  var namelen = sizeof(name).SockLen
-  if getsockname(socket, cast[ptr SockAddr](addr(name)),
-                 addr(namelen)) == -1'i32:
-    raiseOSError(osLastError())
-  result = Port(nativesockets.ntohs(name.sin_port))
+      var s =
+        when defined(android4):
+          posix.gethostbyaddr(cast[cstring](addr(myaddr)), sizeof(myaddr).cint,
+                              cint(posix.AF_INET))
+        else:
+          posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).SockLen,
+                              cint(posix.AF_INET))
+      if s == nil:
+        raiseOSError(osLastError(), $hstrerror(h_errno))
+
+    result.name = $s.h_name
+    result.aliases = cstringArrayToSeq(s.h_aliases)
+    when useWinVersion:
+      result.addrtype = Domain(s.h_addrtype)
+    else:
+      if s.h_addrtype == posix.AF_INET:
+        result.addrtype = AF_INET
+      elif s.h_addrtype == posix.AF_INET6:
+        result.addrtype = AF_INET6
+      else:
+        raiseOSError(osLastError(), "unknown h_addrtype")
+    if result.addrtype == AF_INET:
+      result.addrList = @[]
+      var i = 0
+      while not isNil(s.h_addr_list[i]):
+        var inaddrPtr = cast[ptr InAddr](s.h_addr_list[i])
+        result.addrList.add($inet_ntoa(inaddrPtr[]))
+        inc(i)
+    else:
+      result.addrList = cstringArrayToSeq(s.h_addr_list)
+    result.length = int(s.h_length)
 
-proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
-  ## Returns the socket's local address and port number.
-  ##
-  ## Similar to POSIX's `getsockname`:idx:.
-  case domain
-  of AF_INET:
-    var name: Sockaddr_in
+  proc getHostByName*(name: string): Hostent {.tags: [ReadIOEffect].} =
+    ## This function will lookup the IP address of a hostname.
     when useWinVersion:
-      name.sin_family = uint16(ord(AF_INET))
+      var s = winlean.gethostbyname(name)
     else:
-      name.sin_family = TSa_Family(posix.AF_INET)
-    var namelen = sizeof(name).SockLen
-    if getsockname(socket, cast[ptr SockAddr](addr(name)),
-                   addr(namelen)) == -1'i32:
-      raiseOSError(osLastError())
-    result = ($inet_ntoa(name.sin_addr),
-              Port(nativesockets.ntohs(name.sin_port)))
-  of AF_INET6:
-    var name: Sockaddr_in6
+      var s = posix.gethostbyname(name)
+    if s == nil: raiseOSError(osLastError())
+    result.name = $s.h_name
+    result.aliases = cstringArrayToSeq(s.h_aliases)
     when useWinVersion:
-      name.sin6_family = uint16(ord(AF_INET6))
+      result.addrtype = Domain(s.h_addrtype)
     else:
-      name.sin6_family = TSa_Family(posix.AF_INET6)
-    var namelen = sizeof(name).SockLen
-    if getsockname(socket, cast[ptr SockAddr](addr(name)),
-                   addr(namelen)) == -1'i32:
-      raiseOSError(osLastError())
-    # Cannot use INET6_ADDRSTRLEN here, because it's a C define.
-    result[0] = newString(64)
-    if inet_ntop(name.sin6_family.cint,
-        addr name.sin6_addr, addr result[0][0], (result[0].len+1).int32).isNil:
+      if s.h_addrtype == posix.AF_INET:
+        result.addrtype = AF_INET
+      elif s.h_addrtype == posix.AF_INET6:
+        result.addrtype = AF_INET6
+      else:
+        raiseOSError(osLastError(), "unknown h_addrtype")
+    if result.addrtype == AF_INET:
+      result.addrList = @[]
+      var i = 0
+      while not isNil(s.h_addr_list[i]):
+        var inaddrPtr = cast[ptr InAddr](s.h_addr_list[i])
+        result.addrList.add($inet_ntoa(inaddrPtr[]))
+        inc(i)
+    else:
+      result.addrList = cstringArrayToSeq(s.h_addr_list)
+    result.length = int(s.h_length)
+
+  proc getHostname*(): string {.tags: [ReadIOEffect].} =
+    ## Returns the local hostname (not the FQDN)
+    # https://tools.ietf.org/html/rfc1035#section-2.3.1
+    # https://tools.ietf.org/html/rfc2181#section-11
+    const size = 256
+    result = newString(size)
+    when useWinVersion:
+      let success = winlean.gethostname(result, size)
+    else:
+      # Posix
+      let success = posix.gethostname(result, size)
+    if success != 0.cint:
       raiseOSError(osLastError())
-    setLen(result[0], result[0].cstring.len)
-    result[1] = Port(nativesockets.ntohs(name.sin6_port))
-  else:
-    raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
-
-proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
-  ## Returns the socket's peer address and port number.
-  ##
-  ## Similar to POSIX's `getpeername`:idx:
-  case domain
-  of AF_INET:
+    let x = len(cstring(result))
+    result.setLen(x)
+
+  proc getAddrString*(sockAddr: ptr SockAddr): string =
+    ## Returns the string representation of address within sockAddr
+    if sockAddr.sa_family.cint == nativeAfInet:
+      result = $inet_ntoa(cast[ptr Sockaddr_in](sockAddr).sin_addr)
+    elif sockAddr.sa_family.cint == nativeAfInet6:
+      let addrLen = when not useWinVersion: posix.INET6_ADDRSTRLEN.int
+                    else: 46 # it's actually 46 in both cases
+      result = newString(addrLen)
+      let addr6 = addr cast[ptr Sockaddr_in6](sockAddr).sin6_addr
+      when not useWinVersion:
+        if posix.inet_ntop(posix.AF_INET6, addr6, addr result[0],
+                          result.len.int32) == nil:
+          raiseOSError(osLastError())
+        if posix.IN6_IS_ADDR_V4MAPPED(addr6) != 0:
+          result.setSlice("::ffff:".len..<addrLen)
+      else:
+        if winlean.inet_ntop(winlean.AF_INET6, addr6, addr result[0],
+                            result.len.int32) == nil:
+          raiseOSError(osLastError())
+      setLen(result, len(cstring(result)))
+    else:
+      when defined(posix) and not defined(nimdoc):
+        if sockAddr.sa_family.cint == nativeAfUnix:
+          return "unix"
+      raise newException(IOError, "Unknown socket family in getAddrString")
+
+  proc getAddrString*(sockAddr: ptr SockAddr, strAddress: var string) =
+    ## Stores in `strAddress` the string representation of the address inside
+    ## `sockAddr`
+    ##
+    ## **Note**
+    ## * `strAddress` must be initialized to 46 in length.
+    const length = 46
+    assert(length == len(strAddress),
+          "`strAddress` was not initialized correctly. 46 != `len(strAddress)`")
+    if sockAddr.sa_family.cint == nativeAfInet:
+      let addr4 = addr cast[ptr Sockaddr_in](sockAddr).sin_addr
+      when not useWinVersion:
+        if posix.inet_ntop(posix.AF_INET, addr4, addr strAddress[0],
+                          strAddress.len.int32) == nil:
+          raiseOSError(osLastError())
+      else:
+        if winlean.inet_ntop(winlean.AF_INET, addr4, addr strAddress[0],
+                            strAddress.len.int32) == nil:
+          raiseOSError(osLastError())
+    elif sockAddr.sa_family.cint == nativeAfInet6:
+      let addr6 = addr cast[ptr Sockaddr_in6](sockAddr).sin6_addr
+      when not useWinVersion:
+        if posix.inet_ntop(posix.AF_INET6, addr6, addr strAddress[0],
+                          strAddress.len.int32) == nil:
+          raiseOSError(osLastError())
+        if posix.IN6_IS_ADDR_V4MAPPED(addr6) != 0:
+          strAddress.setSlice("::ffff:".len..<length)
+      else:
+        if winlean.inet_ntop(winlean.AF_INET6, addr6, addr strAddress[0],
+                            strAddress.len.int32) == nil:
+          raiseOSError(osLastError())
+    else:
+      raise newException(IOError, "Unknown socket family in getAddrString")
+    setLen(strAddress, len(cstring(strAddress)))
+
+  when defined(posix) and not defined(nimdoc):
+    proc makeUnixAddr*(path: string): Sockaddr_un =
+      result.sun_family = AF_UNIX.TSa_Family
+      if path.len >= Sockaddr_un_path_length:
+        raise newException(ValueError, "socket path too long")
+      copyMem(addr result.sun_path, path.cstring, path.len + 1)
+
+  proc getSockName*(socket: SocketHandle): Port =
+    ## Returns the socket's associated port number.
     var name: Sockaddr_in
     when useWinVersion:
       name.sin_family = uint16(ord(AF_INET))
     else:
       name.sin_family = TSa_Family(posix.AF_INET)
+    #name.sin_port = htons(cint16(port))
+    #name.sin_addr.s_addr = htonl(INADDR_ANY)
     var namelen = sizeof(name).SockLen
-    if getpeername(socket, cast[ptr SockAddr](addr(name)),
-                   addr(namelen)) == -1'i32:
+    if getsockname(socket, cast[ptr SockAddr](addr(name)),
+                  addr(namelen)) == -1'i32:
       raiseOSError(osLastError())
-    result = ($inet_ntoa(name.sin_addr),
-              Port(nativesockets.ntohs(name.sin_port)))
-  of AF_INET6:
-    var name: Sockaddr_in6
-    when useWinVersion:
-      name.sin6_family = uint16(ord(AF_INET6))
+    result = Port(nativesockets.ntohs(name.sin_port))
+
+  proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
+    ## Returns the socket's local address and port number.
+    ##
+    ## Similar to POSIX's `getsockname`:idx:.
+    case domain
+    of AF_INET:
+      var name: Sockaddr_in
+      when useWinVersion:
+        name.sin_family = uint16(ord(AF_INET))
+      else:
+        name.sin_family = TSa_Family(posix.AF_INET)
+      var namelen = sizeof(name).SockLen
+      if getsockname(socket, cast[ptr SockAddr](addr(name)),
+                    addr(namelen)) == -1'i32:
+        raiseOSError(osLastError())
+      result = ($inet_ntoa(name.sin_addr),
+                Port(nativesockets.ntohs(name.sin_port)))
+    of AF_INET6:
+      var name: Sockaddr_in6
+      when useWinVersion:
+        name.sin6_family = uint16(ord(AF_INET6))
+      else:
+        name.sin6_family = TSa_Family(posix.AF_INET6)
+      var namelen = sizeof(name).SockLen
+      if getsockname(socket, cast[ptr SockAddr](addr(name)),
+                    addr(namelen)) == -1'i32:
+        raiseOSError(osLastError())
+      # Cannot use INET6_ADDRSTRLEN here, because it's a C define.
+      result[0] = newString(64)
+      if inet_ntop(name.sin6_family.cint,
+          addr name.sin6_addr, addr result[0][0], (result[0].len+1).int32).isNil:
+        raiseOSError(osLastError())
+      setLen(result[0], result[0].cstring.len)
+      result[1] = Port(nativesockets.ntohs(name.sin6_port))
     else:
-      name.sin6_family = TSa_Family(posix.AF_INET6)
-    var namelen = sizeof(name).SockLen
-    if getpeername(socket, cast[ptr SockAddr](addr(name)),
-                   addr(namelen)) == -1'i32:
-      raiseOSError(osLastError())
-    # Cannot use INET6_ADDRSTRLEN here, because it's a C define.
-    result[0] = newString(64)
-    if inet_ntop(name.sin6_family.cint,
-        addr name.sin6_addr, addr result[0][0], (result[0].len+1).int32).isNil:
+      raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
+
+  proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
+    ## Returns the socket's peer address and port number.
+    ##
+    ## Similar to POSIX's `getpeername`:idx:
+    case domain
+    of AF_INET:
+      var name: Sockaddr_in
+      when useWinVersion:
+        name.sin_family = uint16(ord(AF_INET))
+      else:
+        name.sin_family = TSa_Family(posix.AF_INET)
+      var namelen = sizeof(name).SockLen
+      if getpeername(socket, cast[ptr SockAddr](addr(name)),
+                    addr(namelen)) == -1'i32:
+        raiseOSError(osLastError())
+      result = ($inet_ntoa(name.sin_addr),
+                Port(nativesockets.ntohs(name.sin_port)))
+    of AF_INET6:
+      var name: Sockaddr_in6
+      when useWinVersion:
+        name.sin6_family = uint16(ord(AF_INET6))
+      else:
+        name.sin6_family = TSa_Family(posix.AF_INET6)
+      var namelen = sizeof(name).SockLen
+      if getpeername(socket, cast[ptr SockAddr](addr(name)),
+                    addr(namelen)) == -1'i32:
+        raiseOSError(osLastError())
+      # Cannot use INET6_ADDRSTRLEN here, because it's a C define.
+      result[0] = newString(64)
+      if inet_ntop(name.sin6_family.cint,
+          addr name.sin6_addr, addr result[0][0], (result[0].len+1).int32).isNil:
+        raiseOSError(osLastError())
+      setLen(result[0], result[0].cstring.len)
+      result[1] = Port(nativesockets.ntohs(name.sin6_port))
+    else:
+      raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
+
+when useNimNetLite: 
+
+  when useWinVersion:
+    const
+      INET_ADDRSTRLEN = 16
+      INET6_ADDRSTRLEN = 46 # it's actually 46 in both cases
+
+  proc sockAddrToStr(sa: ptr Sockaddr): string {.noinit.} =
+    let af_family = sa.sa_family 
+    var nl, v4Slice: cint
+    var si_addr: ptr InAddr
+
+    if af_family == AF_INET.TSa_Family:
+      nl = INET_ADDRSTRLEN
+      si_addr = cast[ptr Sockaddr_in](sa).sin_addr.addr()
+    elif af_family == AF_INET6.TSa_Family:
+      nl = INET6_ADDRSTRLEN
+      let si6_addr = cast[ptr Sockaddr_in6](sa).sin6_addr.addr()
+      si_addr = cast[ptr InAddr](si6_addr) # let's us reuse logic below 
+      when defined(posix) and not defined(nimdoc) and not defined(zephyr):
+        if posix.IN6_IS_ADDR_V4MAPPED(si6_addr) != 0:
+          v4Slice = "::ffff:".len()
+    else:
+      when defined(posix) and not defined(nimdoc):
+        if af_family.cint == nativeAfUnix:
+          return "unix"
+      return ""
+
+    result = newString(nl)
+    let namePtr = result.cstring()
+    if namePtr == inet_ntop(af_family.cint, si_addr, namePtr, nl):
+      result.setLen(len(namePtr))
+      if v4Slice > 0: result.setSlice(v4Slice.int ..< nl.int)
+    else:
+      return ""
+
+  proc sockAddrToStr(sa: var Sockaddr_in | var Sockaddr_in6): string =
+    result = sockAddrToStr(cast[ptr SockAddr](unsafeAddr(sa)))
+
+  proc getAddrString*(sockAddr: ptr SockAddr): string =
+    result = sockAddrToStr(sockAddr)
+    if result.len() == 0:
       raiseOSError(osLastError())
-    setLen(result[0], result[0].cstring.len)
-    result[1] = Port(nativesockets.ntohs(name.sin6_port))
-  else:
-    raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
+
+  proc getAddrString*(sockAddr: ptr SockAddr, strAddress: var string) {.noinit.} =
+    strAddress = getAddrString(sockAddr)
+
+  proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
+    ## Returns the socket's local address and port number.
+    ##
+    ## Similar to POSIX's `getsockname`:idx:.
+    template sockGetNameOrRaiseError(socket: untyped, name: untyped) =
+      var namelen = sizeof(socket).SockLen
+      if getsockname(socket, cast[ptr SockAddr](addr(name)),
+                    addr(namelen)) == -1'i32:
+        raiseOSError(osLastError())
+
+    case domain
+    of AF_INET:
+      var name = Sockaddr_in(sin_family: TSa_Family(posix.AF_INET))
+      sockGetNameOrRaiseError(socket, name)
+      result = (sockAddrToStr(name),
+                Port(nativesockets.ntohs(name.sin_port)))
+    of AF_INET6:
+      var name = Sockaddr_in6(sin6_family: TSa_Family(posix.AF_INET6))
+      sockGetNameOrRaiseError(socket, name)
+      result = (sockAddrToStr(name),
+                Port(nativesockets.ntohs(name.sin6_port)))
+    else:
+      raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
+
 
 proc getSockOptInt*(socket: SocketHandle, level, optname: int): int {.
   tags: [ReadIOEffect].} =
@@ -733,14 +810,14 @@ proc accept*(fd: SocketHandle, inheritable = defined(nimInheritHandles)): (Socke
   ## child processes.
   ##
   ## Returns (osInvalidSocket, "") if an error occurred.
-  var sockAddress: Sockaddr_in
+  var sockAddress: Sockaddr
   var addrLen = sizeof(sockAddress).SockLen
   var sock =
     when (defined(linux) or defined(bsd)) and not defined(nimdoc):
-      accept4(fd, cast[ptr SockAddr](addr(sockAddress)), addr(addrLen),
+      accept4(fd, addr(sockAddress), addr(addrLen),
               if inheritable: 0 else: SOCK_CLOEXEC)
     else:
-      accept(fd, cast[ptr SockAddr](addr(sockAddress)), addr(addrLen))
+      accept(fd, addr(sockAddress), addr(addrLen))
   when declared(setInheritable) and not (defined(linux) or defined(bsd)):
     if not setInheritable(sock, inheritable):
       close sock
@@ -748,7 +825,11 @@ proc accept*(fd: SocketHandle, inheritable = defined(nimInheritHandles)): (Socke
   if sock == osInvalidSocket:
     return (osInvalidSocket, "")
   else:
-    return (sock, $inet_ntoa(sockAddress.sin_addr))
+    when useNimNetLite:
+      var name = sockAddrToStr(addr sockAddress)
+      return (sock, name)
+    else:
+      return (sock, $inet_ntoa(cast[Sockaddr_in](sockAddress).sin_addr))
 
 when defined(windows):
   var wsa: WSAData
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index 09cdc8afb..7b0ff78e7 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -85,12 +85,14 @@ runnableExamples("-r:off"):
 
 import std/private/since
 
-import nativesockets, os, strutils, times, sets, options, std/monotimes
+import nativesockets
+import os, strutils, times, sets, options, std/monotimes
 import ssl_config
 export nativesockets.Port, nativesockets.`$`, nativesockets.`==`
 export Domain, SockType, Protocol
 
 const useWinVersion = defined(windows) or defined(nimdoc)
+const useNimNetLite = defined(nimNetLite) or defined(freertos) or defined(zephyr)
 const defineSsl = defined(ssl) or defined(nimdoc)
 
 when useWinVersion:
@@ -1243,11 +1245,12 @@ proc getLocalAddr*(socket: Socket): (string, Port) =
   ## This is high-level interface for `getsockname`:idx:.
   getLocalAddr(socket.fd, socket.domain)
 
-proc getPeerAddr*(socket: Socket): (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: Socket): (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 setSockOpt*(socket: Socket, opt: SOBool, value: bool,
     level = SOL_SOCKET) {.tags: [WriteIOEffect].} =
@@ -1259,7 +1262,7 @@ proc setSockOpt*(socket: Socket, opt: SOBool, value: bool,
   var valuei = cint(if value: 1 else: 0)
   setSockOptInt(socket.fd, cint(level), toCInt(opt), valuei)
 
-when defined(posix) or defined(nimdoc):
+when defined(nimdoc) or (defined(posix) and not useNimNetLite):
   proc connectUnix*(socket: Socket, path: string) =
     ## Connects to Unix socket on `path`.
     ## This only works on Unix-style systems: Mac OS X, BSD and Linux
diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim
index 82550e09b..ec441f6da 100644
--- a/lib/pure/selectors.nim
+++ b/lib/pure/selectors.nim
@@ -323,6 +323,23 @@ else:
     # Anything higher is the time to wait in milliseconds.
     doAssert(timeout >= -1, "Cannot select with a negative value, got: " & $timeout)
 
+  when defined(linux) or defined(windows) or defined(macosx) or defined(bsd) or
+       defined(zephyr) or defined(freertos):
+    template maxDescriptors*(): int =
+      ## Returns the maximum number of active file descriptors for the current
+      ## process. This involves a system call. For now `maxDescriptors` is
+      ## supported on the following OSes: Windows, Linux, OSX, BSD.
+      when defined(windows):
+        16_700_000
+      elif defined(zephyr) or defined(freertos):
+        FD_MAX
+      else:
+        var fdLim: RLimit
+        var res = int(getrlimit(RLIMIT_NOFILE, fdLim))
+        if res >= 0:
+          res = int(fdLim.rlim_cur) - 1
+        res
+
   when defined(linux) and not defined(emscripten):
     include ioselects/ioselectors_epoll
   elif bsdPlatform:
@@ -337,5 +354,7 @@ else:
     include ioselects/ioselectors_select
   elif defined(freertos) or defined(lwip):
     include ioselects/ioselectors_select
+  elif defined(zephyr):
+    include ioselects/ioselectors_poll
   else:
     include ioselects/ioselectors_poll