From 177bb30013c8d8b648e6e2b3214f1cd03f24c344 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Tue, 1 Aug 2023 11:26:39 +0300 Subject: [PATCH] net: change default of the socket used by net.listen_tcp, to dualstack, even if the OS has a different default. Allow changing the listen backlog too With this change, example vweb programs, will continue to be available to both ipv6 and ipv4 connections from the same machine, even after doing (on linux): `echo 1 | sudo tee /proc/sys/net/ipv6/bindv6only` Previously, after that, vweb programs responded only to ipv6 connections, but not to ipv4 ones, i.e. opening http://127.0.0.1:8082/ stopped working, for `v run examples/vweb/vweb_example.v` . Note: GO web servers have the same behaviour, which is convenient for development/testing, since it makes the programs more consistent and robust in the face of OS settings changes. --- vlib/net/tcp.v | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/vlib/net/tcp.v b/vlib/net/tcp.v index cb20037a64..6dd7d90383 100644 --- a/vlib/net/tcp.v +++ b/vlib/net/tcp.v @@ -284,20 +284,27 @@ mut: accept_deadline time.Time } -pub fn listen_tcp(family AddrFamily, saddr string) !&TcpListener { - s := new_tcp_socket(family) or { return error('${err.msg()}; could not create new socket') } +[params] +pub struct ListenOptions { +pub: + dualstack bool = true + backlog int = 128 +} + +pub fn listen_tcp(family AddrFamily, saddr string, options ListenOptions) !&TcpListener { + mut s := new_tcp_socket(family) or { return error('${err.msg()}; could not create new socket') } + s.set_dualstack(options.dualstack) or {} addrs := resolve_addrs(saddr, family, .tcp) or { return error('${err.msg()}; could not resolve address ${saddr}') } - // TODO(logic to pick here) addr := addrs[0] // cast to the correct type alen := addr.len() socket_error_message(C.bind(s.handle, voidptr(&addr), alen), 'binding to ${saddr} failed')! - socket_error_message(C.listen(s.handle, 128), 'listening on ${saddr} failed')! + socket_error_message(C.listen(s.handle, options.backlog), 'listening on ${saddr} with maximum backlog pending queue of ${options.backlog}, failed')! return &TcpListener{ sock: s accept_deadline: no_deadline