// // Copyright (c) 2021, Brian Frank and Andy Frank // Licensed under the Academic Free License version 3.0 // // History: // 20 Aug 2021 Matthew Giannini Creation // using concurrent using crypto ** ** Configuration options for TCP and UDP sockets. All socket types accept ** a socket configuration which will be used to configure the socket when ** it is created. ** ** A system-wide default socket configuration can be obtained with ** `SocketConfig.cur`. You can change the system default by using ** `SocketConfig.setCur`. ** ** See `TcpSocket.make`, `TcpListener.make`, `UdpSocket.make`, `MulticastSocket.make` ** const class SocketConfig { ////////////////////////////////////////////////////////////////////////// // Cur ////////////////////////////////////////////////////////////////////////// ** Get the current, default socket configuration static SocketConfig cur() { curRef.val } ** Set a new default socket configuration. This configuration will ** only apply to new sockets created after this is called. This ** method may only be called **once** to change the default socket configuration. static Void setCur(SocketConfig cfg) { if (errRef.val != null) throw Err("Default socket configuration already set", errRef.val) curRef.val = cfg errRef.val = Err("Default socket configuration changed") } private static const AtomicRef curRef := AtomicRef(SocketConfig()) private static const AtomicRef errRef := AtomicRef() ////////////////////////////////////////////////////////////////////////// // Constructor ////////////////////////////////////////////////////////////////////////// ** Create and configure the socket options. new make(|This|? f := null) { f?.call(this) } @NoDoc new makeCopy(SocketConfig? orig, |This| f) { if (orig != null) { this.keystore = orig.keystore this.truststore = orig.truststore this.tlsParams = orig.tlsParams this.inBufferSize = orig.inBufferSize this.keepAlive = orig.keepAlive this.receiveBufferSize = orig.receiveBufferSize this.sendBufferSize = orig.sendBufferSize this.reuseAddr = orig.reuseAddr this.linger = orig.linger this.connectTimeout = orig.connectTimeout this.receiveTimeout = orig.receiveTimeout this.acceptTimeout = orig.acceptTimeout this.noDelay = orig.noDelay this.trafficClass = orig.trafficClass this.broadcast = orig.broadcast } f(this) } ** Create a copy of this configuration and then apply any overrides from the it-block. virtual This copy(|This| f) { makeCopy(this, f) } ** Convenience to create a copy of this socket configuration and set the connect ** and receive timeouts to the given duration. Setting to 'null' indicates ** infinite timeouts. This setTimeouts(Duration? connectTimeout, Duration? receiveTimeout := connectTimeout) { makeCopy(this) { it.connectTimeout = connectTimeout; it.receiveTimeout = receiveTimeout } } private native Void force_peer() ////////////////////////////////////////////////////////////////////////// // Tls Config ////////////////////////////////////////////////////////////////////////// ** The `crypto::KeyStore` to use when creating secure sockets. If null, the runtime ** default will be used. const KeyStore? keystore := null ** The `crypto::KeyStore` to use for obtaining trusted certificates when creating ** secure sockets. If null, the runtime default will be used. const KeyStore? truststore := null ** TCP sockets that are upgraded to TLS will be configured with these parameters. ** The following parameters are supported: ** - 'appProtocols': ('Str[]') prioritized array of application-layer protocol ** names that can be negotiated over the TLS protocol ** ** **Experimental - this functionality is subject to change** @NoDoc const Str:Obj? tlsParams := [:] ////////////////////////////////////////////////////////////////////////// // Socket Config ////////////////////////////////////////////////////////////////////////// ** The size in bytes for the sys::InStream buffer. A value of 0 or ** null disables input stream buffing. const Int? inBufferSize := 4096 ** The size in bytes for the sys::OutStream buffer. A value of 0 or ** null disables output stream buffing. const Int? outBufferSize := 4096 ** 'SO_KEEPALIVE' option const Bool keepAlive := false ** 'SO_RCVBUF' option for the size in bytes of the IP stack buffers. const Int receiveBufferSize := 65_536 ** 'SO_SNDBUF' option for the size in bytes of the IP stack buffers. const Int sendBufferSize := 65_536 ** 'SO_REUSEADDR' is used to control the time wait state of a closed socket. const Bool reuseAddr := false ** 'SO_LINGER' controls the linger time or set to null to disable linger. const Duration? linger := null ** Controls the default timeout used by `TcpSocket.connect`. ** A null value indicates a system default timeout (usually wait forever). const Duration? connectTimeout := 60sec ** 'SO_TIMEOUT' controls the amount of time a socket ** will block on a read call before throwing an IOErr timeout exception. ** 'null' is used to indicate an infinite timeout. const Duration? receiveTimeout := 60sec ** Controls how long a `TcpListener.accept` will block before throwing an ** IOErr timeout exception. 'null' is used to indicate infinite timeout. const Duration? acceptTimeout := null ** 'TCP_NODELAY' socket option specifies that send not be delayed ** to merge packets (Nagle's algorthm). const Bool noDelay := true ** The type-of-class byte in the IP packet header. ** ** For IPv4 this value is detailed in RFC 1349 as the following bitset: ** - IPTOS_LOWCOST (0x02) ** - IPTOS_RELIABILITY (0x04) ** - IPTOS_THROUGHPUT (0x08) ** - IPTOS_LOWDELAY (0x10) ** ** For IPv6 this is the value placed into the sin6_flowinfo header field. const Int trafficClass := 0 ** 'SO_BROADCAST' socket option const Bool broadcast := false }