# # Asyncdispatch2 Transport Common Types # (c) Copyright 2018 # Status Research & Development GmbH # # Licensed under either of # Apache License, version 2.0, (LICENSE-APACHEv2) # MIT license (LICENSE-MIT) import net, nativesockets, strutils import ../asyncloop const DefaultStreamBufferSize* = 4096 ## Default buffer size for stream ## transports DefaultDatagramBufferSize* = 65536 ## Default buffer size for datagram ## transports type ServerFlags* = enum ## Server's flags ReuseAddr, ReusePort, NoAutoRead TransportAddress* = object ## Transport network address address*: IpAddress # IP Address port*: Port # IP port ServerCommand* = enum ## Server's commands Start, # Start server Pause, # Pause server Stop # Stop server ServerStatus* = enum ## Server's statuses Starting, # Server created Stopped, # Server stopped Running, # Server running Closed # Server closed FutureGCString*[T] = ref object of Future[T] ## Future to hold GC strings gcholder*: string FutureGCSeq*[A, B] = ref object of Future[A] ## Future to hold GC seqs gcholder*: seq[B] when defined(windows): type SocketServer* = ref object of RootRef ## Socket server object sock*: AsyncFD # Socket local*: TransportAddress # Address status*: ServerStatus # Current server status udata*: pointer # User-defined pointer flags*: set[ServerFlags] # Flags bufferSize*: int # Size of internal transports' buffer loopFuture*: Future[void] # Server's main Future domain*: Domain # Current server domain (IPv4 or IPv6) apending*: bool asock*: AsyncFD # Current AcceptEx() socket abuffer*: array[128, byte] # Windows AcceptEx() buffer aovl*: CustomOverlapped # AcceptEx OVERLAPPED structure else: type SocketServer* = ref object of RootRef ## Socket server object sock*: AsyncFD # Socket local*: TransportAddress # Address status*: ServerStatus # Current server status udata*: pointer # User-defined pointer flags*: set[ServerFlags] # Flags bufferSize*: int # Size of internal transports' buffer loopFuture*: Future[void] # Server's main Future type TransportError* = object of Exception ## Transport's specific exception TransportOsError* = object of TransportError ## Transport's OS specific exception TransportIncompleteError* = object of TransportError ## Transport's `incomplete data received` exception TransportLimitError* = object of TransportError ## Transport's `data limit reached` exception TransportState* = enum ## Transport's state ReadPending, # Read operation pending (Windows) ReadPaused, # Read operations paused ReadClosed, # Read operations closed ReadEof, # Read at EOF ReadError, # Read error WritePending, # Writer operation pending (Windows) WritePaused, # Writer operations paused WriteClosed, # Writer operations closed WriteError # Write error var AnyAddress* = TransportAddress( address: IpAddress(family: IpAddressFamily.IPv4), port: Port(0) ) ## Default INADDR_ANY address for IPv4 AnyAddress6* = TransportAddress( address: IpAddress(family: IpAddressFamily.IPv6), port: Port(0) ) ## Default INADDR_ANY address for IPv6 proc getDomain*(address: IpAddress): Domain = ## Returns OS specific Domain from IP Address. case address.family of IpAddressFamily.IPv4: result = Domain.AF_INET of IpAddressFamily.IPv6: result = Domain.AF_INET6 proc getDomain*(address: TransportAddress): Domain = ## Returns OS specific Domain from TransportAddress. result = address.address.getDomain() proc `$`*(address: TransportAddress): string = ## Returns string representation of ``address``. case address.address.family of IpAddressFamily.IPv4: result = $address.address result.add(":") of IpAddressFamily.IPv6: result = "[" & $address.address & "]" result.add(":") result.add($int(address.port)) proc initTAddress*(address: string): TransportAddress = ## Parses string representation of ``address``. ## ## IPv4 transport address format is ``a.b.c.d:port``. ## IPv6 transport address format is ``[::]:port``. var parts = address.rsplit(":", maxsplit = 1) doAssert(len(parts) == 2, "Format is
: