From 833333e1311b531ffbf3f7051da1ec5287a682b5 Mon Sep 17 00:00:00 2001 From: kobra Date: Thu, 12 Sep 2013 00:46:32 +0100 Subject: Added ability to set the option `reuseport` of a tcp socket. --- src/tcp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/tcp.c') diff --git a/src/tcp.c b/src/tcp.c index 6594bda..d0658a3 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -71,6 +71,7 @@ static luaL_Reg tcp_methods[] = { static t_opt optget[] = { {"keepalive", opt_get_keepalive}, {"reuseaddr", opt_get_reuseaddr}, + {"reuseport", opt_get_reuseport}, {"tcp-nodelay", opt_get_tcp_nodelay}, {"linger", opt_get_linger}, {"error", opt_get_error}, @@ -80,6 +81,7 @@ static t_opt optget[] = { static t_opt optset[] = { {"keepalive", opt_set_keepalive}, {"reuseaddr", opt_set_reuseaddr}, + {"reuseport", opt_set_reuseport}, {"tcp-nodelay", opt_set_tcp_nodelay}, {"ipv6-v6only", opt_set_ip6_v6only}, {"linger", opt_set_linger}, -- cgit v1.2.3-55-g6feb From 2906d6a5227df25f14305c373fdde057f388d363 Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Fri, 5 Dec 2014 13:17:50 +0100 Subject: Add "tcp-keepidle", "tcp-keepcnt" and "tcp-keepintvl" options --- doc/tcp.html | 6 ++++++ src/options.c | 36 ++++++++++++++++++++++++++++++++++++ src/options.h | 18 ++++++++++++++++++ src/tcp.c | 18 ++++++++++++++++++ test/tcp-getoptions | 4 +++- 5 files changed, 81 insertions(+), 1 deletion(-) (limited to 'src/tcp.c') diff --git a/doc/tcp.html b/doc/tcp.html index 4226d78..4307234 100644 --- a/doc/tcp.html +++ b/doc/tcp.html @@ -433,6 +433,12 @@ used in validating addresses supplied in a call to
  • 'tcp-nodelay': Setting this option to true disables the Nagle's algorithm for the connection; +
  • 'tcp-keepidle': value in seconds for TCP_KEEPIDLE Linux only!! + +
  • 'tcp-keepcnt': value for TCP_KEEPCNT Linux only!! + +
  • 'tcp-keepintvl': value for TCP_KEEPINTVL Linux only!! +
  • 'ipv6-v6only': Setting this option to true restricts an inet6 socket to sending and receiving only IPv6 packets. diff --git a/src/options.c b/src/options.c index 8ac2a14..28fc08a 100644 --- a/src/options.c +++ b/src/options.c @@ -90,6 +90,42 @@ int opt_get_tcp_nodelay(lua_State *L, p_socket ps) return opt_getboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); } +#ifdef TCP_KEEPIDLE +int opt_get_tcp_keepidle(lua_State *L, p_socket ps) +{ + return opt_getint(L, ps, IPPROTO_TCP, TCP_KEEPIDLE); +} + +int opt_set_tcp_keepidle(lua_State *L, p_socket ps) +{ + return opt_setint(L, ps, IPPROTO_TCP, TCP_KEEPIDLE); +} +#endif + +#ifdef TCP_KEEPCNT +int opt_get_tcp_keepcnt(lua_State *L, p_socket ps) +{ + return opt_getint(L, ps, IPPROTO_TCP, TCP_KEEPCNT); +} + +int opt_set_tcp_keepcnt(lua_State *L, p_socket ps) +{ + return opt_setint(L, ps, IPPROTO_TCP, TCP_KEEPCNT); +} +#endif + +#ifdef TCP_KEEPINTVL +int opt_get_tcp_keepintvl(lua_State *L, p_socket ps) +{ + return opt_getint(L, ps, IPPROTO_TCP, TCP_KEEPINTVL); +} + +int opt_set_tcp_keepintvl(lua_State *L, p_socket ps) +{ + return opt_setint(L, ps, IPPROTO_TCP, TCP_KEEPINTVL); +} +#endif + int opt_set_keepalive(lua_State *L, p_socket ps) { return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); diff --git a/src/options.h b/src/options.h index 5657a06..2b6697b 100644 --- a/src/options.h +++ b/src/options.h @@ -23,6 +23,15 @@ int opt_set_dontroute(lua_State *L, p_socket ps); int opt_set_broadcast(lua_State *L, p_socket ps); int opt_set_reuseaddr(lua_State *L, p_socket ps); int opt_set_tcp_nodelay(lua_State *L, p_socket ps); +#ifdef TCP_KEEPIDLE +int opt_set_tcp_keepidle(lua_State *L, p_socket ps); +#endif +#ifdef TCP_KEEPCNT +int opt_set_tcp_keepcnt(lua_State *L, p_socket ps); +#endif +#ifdef TCP_KEEPINTVL +int opt_set_tcp_keepintvl(lua_State *L, p_socket ps); +#endif int opt_set_keepalive(lua_State *L, p_socket ps); int opt_set_linger(lua_State *L, p_socket ps); int opt_set_reuseaddr(lua_State *L, p_socket ps); @@ -42,6 +51,15 @@ int opt_set_ip6_v6only(lua_State *L, p_socket ps); /* supported options for getoption */ int opt_get_reuseaddr(lua_State *L, p_socket ps); int opt_get_tcp_nodelay(lua_State *L, p_socket ps); +#ifdef TCP_KEEPIDLE +int opt_get_tcp_keepidle(lua_State *L, p_socket ps); +#endif +#ifdef TCP_KEEPCNT +int opt_get_tcp_keepcnt(lua_State *L, p_socket ps); +#endif +#ifdef TCP_KEEPINTVL +int opt_get_tcp_keepintvl(lua_State *L, p_socket ps); +#endif int opt_get_keepalive(lua_State *L, p_socket ps); int opt_get_linger(lua_State *L, p_socket ps); int opt_get_reuseaddr(lua_State *L, p_socket ps); diff --git a/src/tcp.c b/src/tcp.c index 6594bda..3af9a39 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -72,6 +72,15 @@ static t_opt optget[] = { {"keepalive", opt_get_keepalive}, {"reuseaddr", opt_get_reuseaddr}, {"tcp-nodelay", opt_get_tcp_nodelay}, +#ifdef TCP_KEEPIDLE + {"tcp-keepidle", opt_get_tcp_keepidle}, +#endif +#ifdef TCP_KEEPCNT + {"tcp-keepcnt", opt_get_tcp_keepcnt}, +#endif +#ifdef TCP_KEEPINTVL + {"tcp-keepintvl", opt_get_tcp_keepintvl}, +#endif {"linger", opt_get_linger}, {"error", opt_get_error}, {NULL, NULL} @@ -81,6 +90,15 @@ static t_opt optset[] = { {"keepalive", opt_set_keepalive}, {"reuseaddr", opt_set_reuseaddr}, {"tcp-nodelay", opt_set_tcp_nodelay}, +#ifdef TCP_KEEPIDLE + {"tcp-keepidle", opt_set_tcp_keepidle}, +#endif +#ifdef TCP_KEEPCNT + {"tcp-keepcnt", opt_set_tcp_keepcnt}, +#endif +#ifdef TCP_KEEPINTVL + {"tcp-keepintvl", opt_set_tcp_keepintvl}, +#endif {"ipv6-v6only", opt_set_ip6_v6only}, {"linger", opt_set_linger}, {NULL, NULL} diff --git a/test/tcp-getoptions b/test/tcp-getoptions index f9b3d1b..777ccc3 100755 --- a/test/tcp-getoptions +++ b/test/tcp-getoptions @@ -7,7 +7,9 @@ port = 8765 function options(o) print("options for", o) - for _, opt in ipairs{"keepalive", "reuseaddr", "tcp-nodelay"} do + for _, opt in ipairs{ + "keepalive", "reuseaddr", + "tcp-nodelay", "tcp-keepidle", "tcp-keepcnt", "tcp-keepintvl"} do print("getoption", opt, o:getoption(opt)) end -- cgit v1.2.3-55-g6feb From 83880dbed77f9a0a3627bce2e7bfbe1b862e091d Mon Sep 17 00:00:00 2001 From: Diego Nehab Date: Thu, 3 Dec 2015 12:56:18 -0200 Subject: When zero-timeout, only try first address in connect. --- doc/tcp.html | 13 ++++++++----- src/inet.c | 4 ++-- src/tcp.c | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) (limited to 'src/tcp.c') diff --git a/doc/tcp.html b/doc/tcp.html index fb627a1..c86853d 100644 --- a/doc/tcp.html +++ b/doc/tcp.html @@ -242,11 +242,14 @@ established.

    Note: Starting with LuaSocket 3.0, the host name resolution -depends on whether the socket was created by socket.tcp or socket.tcp6. Addresses from -the appropriate family are tried in succession until the -first success or until the last failure. +depends on whether the socket was created by +socket.tcp, +socket.tcp4 or +socket.tcp6. Addresses from +the appropriate family (or both) are tried in the order +returned by the resolver until the +first success or until the last failure. If the timeout was +set to zero, only the first address is tried.

    diff --git a/src/inet.c b/src/inet.c index 331b800..f4c8404 100644 --- a/src/inet.c +++ b/src/inet.c @@ -423,8 +423,8 @@ const char *inet_tryconnect(p_socket ps, int *family, const char *address, /* try connecting to remote address */ err = socket_strerror(socket_connect(ps, (SA *) iterator->ai_addr, (socklen_t) iterator->ai_addrlen, tm)); - /* if success, break out of loop */ - if (err == NULL) { + /* if success or timeout is zero, break out of loop */ + if (err == NULL || timeout_iszero(tm)) { *family = current_family; break; } diff --git a/src/tcp.c b/src/tcp.c index cef9d16..e4f1a4b 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -417,7 +417,7 @@ static int global_connect(lua_State *L) { bindhints.ai_family = family; bindhints.ai_flags = AI_PASSIVE; if (localaddr) { - err = inet_trybind(&tcp->sock, &tcp->family, localaddr, + err = inet_trybind(&tcp->sock, &tcp->family, localaddr, localserv, &bindhints); if (err) { lua_pushnil(L); @@ -429,7 +429,7 @@ static int global_connect(lua_State *L) { memset(&connecthints, 0, sizeof(connecthints)); connecthints.ai_socktype = SOCK_STREAM; /* make sure we try to connect only to the same family */ - connecthints.ai_family = tcp->family; + connecthints.ai_family = tcp->family; err = inet_tryconnect(&tcp->sock, &tcp->family, remoteaddr, remoteserv, &tcp->tm, &connecthints); if (err) { -- cgit v1.2.3-55-g6feb From 944305dc21350fd2ec32a9552d893da86894fd62 Mon Sep 17 00:00:00 2001 From: Diego Nehab Date: Fri, 4 Mar 2016 15:36:32 -0300 Subject: Added gettimeout for completeness. Also documented. Rordered manuals so order is alphabetical. --- doc/mime.html | 59 ++++---- doc/reference.html | 2 + doc/smtp.html | 235 ++++++++++++++--------------- doc/socket.html | 70 ++++----- doc/tcp.html | 283 +++++++++++++++++++---------------- doc/udp.html | 431 +++++++++++++++++++++++++++-------------------------- src/tcp.c | 8 + src/timeout.c | 10 ++ src/timeout.h | 1 + src/udp.c | 7 + 10 files changed, 587 insertions(+), 519 deletions(-) (limited to 'src/tcp.c') diff --git a/doc/mime.html b/doc/mime.html index ae136fd..8cb3507 100644 --- a/doc/mime.html +++ b/doc/mime.html @@ -72,34 +72,6 @@ local mime = require("mime")

    High-level filters

    - - -

    -mime.normalize([marker]) -

    - -

    -Converts most common end-of-line markers to a specific given marker. -

    - -

    -Marker is the new marker. It defaults to CRLF, the canonic -end-of-line marker defined by the MIME standard. -

    - -

    -The function returns a filter that performs the conversion. -

    - -

    -Note: There is no perfect solution to this problem. Different end-of-line -markers are an evil that will probably plague developers forever. -This function, however, will work perfectly for text created with any of -the most common end-of-line markers, i.e. the Mac OS (CR), the Unix (LF), -or the DOS (CRLF) conventions. Even if the data has mixed end-of-line -markers, the function will still work well, although it doesn't -guarantee that the number of empty lines will be correct. -

    @@ -159,6 +131,35 @@ base64 = ltn12.filter.chain( ) + + +

    +mime.normalize([marker]) +

    + +

    +Converts most common end-of-line markers to a specific given marker. +

    + +

    +Marker is the new marker. It defaults to CRLF, the canonic +end-of-line marker defined by the MIME standard. +

    + +

    +The function returns a filter that performs the conversion. +

    + +

    +Note: There is no perfect solution to this problem. Different end-of-line +markers are an evil that will probably plague developers forever. +This function, however, will work perfectly for text created with any of +the most common end-of-line markers, i.e. the Mac OS (CR), the Unix (LF), +or the DOS (CRLF) conventions. Even if the data has mixed end-of-line +markers, the function will still work well, although it doesn't +guarantee that the number of empty lines will be correct. +

    +

    @@ -466,7 +467,7 @@ marker.

    Last modified by Diego Nehab on
    -Thu Apr 20 00:25:44 EDT 2006 +Fri Mar 4 15:19:17 BRT 2016

    diff --git a/doc/reference.html b/doc/reference.html index 878e7d2..287dc19 100644 --- a/doc/reference.html +++ b/doc/reference.html @@ -187,6 +187,7 @@ Support, Manual"> getpeername, getsockname, getstats, +gettimeout, listen, receive, send, @@ -207,6 +208,7 @@ Support, Manual"> getoption, getpeername, getsockname, +gettimeout, receive, receivefrom, send, diff --git a/doc/smtp.html b/doc/smtp.html index bbbff80..600ec37 100644 --- a/doc/smtp.html +++ b/doc/smtp.html @@ -114,6 +114,124 @@ the SMTP module:
  • ZONE: default time zone. + + +

    +smtp.message(mesgt) +

    + +

    +Returns a simple +LTN12 source that sends an SMTP message body, possibly multipart (arbitrarily deep). +

    + +

    +The only parameter of the function is a table describing the message. +Mesgt has the following form (notice the recursive structure): +

    + +
    + + +
    +mesgt = {
    +  headers = header-table,
    +  body = LTN12 source or string or +multipart-mesgt
    +}

    +multipart-mesgt = {
    +  [preamble = string,]
    +  [1] = mesgt,
    +  [2] = mesgt,
    +  ...
    +  [n] = mesgt,
    +  [epilogue = string,]
    +}
    +
    +
    + +

    +For a simple message, all that is needed is a set of headers +and the body. The message body can be given as a string +or as a simple +LTN12 +source. For multipart messages, the body is a table that +recursively defines each part as an independent message, plus an optional +preamble and epilogue. +

    + +

    +The function returns a simple +LTN12 +source that produces the +message contents as defined by mesgt, chunk by chunk. +Hopefully, the following +example will make things clear. When in doubt, refer to the appropriate RFC +as listed in the introduction.

    + +
    +-- load the smtp support and its friends
    +local smtp = require("socket.smtp")
    +local mime = require("mime")
    +local ltn12 = require("ltn12")
    +
    +-- creates a source to send a message with two parts. The first part is 
    +-- plain text, the second part is a PNG image, encoded as base64.
    +source = smtp.message{
    +  headers = {
    +     -- Remember that headers are *ignored* by smtp.send. 
    +     from = "Sicrano de Oliveira <sicrano@example.com>",
    +     to = "Fulano da Silva <fulano@example.com>",
    +     subject = "Here is a message with attachments"
    +  },
    +  body = {
    +    preamble = "If your client doesn't understand attachments, \r\n" ..
    +               "it will still display the preamble and the epilogue.\r\n" ..
    +               "Preamble will probably appear even in a MIME enabled client.",
    +    -- first part: no headers means plain text, us-ascii.
    +    -- The mime.eol low-level filter normalizes end-of-line markers.
    +    [1] = { 
    +      body = mime.eol(0, [[
    +        Lines in a message body should always end with CRLF. 
    +        The smtp module will *NOT* perform translation. However, the 
    +        send function *DOES* perform SMTP stuffing, whereas the message
    +        function does *NOT*.
    +      ]])
    +    },
    +    -- second part: headers describe content to be a png image, 
    +    -- sent under the base64 transfer content encoding.
    +    -- notice that nothing happens until the message is actually sent. 
    +    -- small chunks are loaded into memory right before transmission and 
    +    -- translation happens on the fly.
    +    [2] = { 
    +      headers = {
    +        ["content-type"] = 'image/png; name="image.png"',
    +        ["content-disposition"] = 'attachment; filename="image.png"',
    +        ["content-description"] = 'a beautiful image',
    +        ["content-transfer-encoding"] = "BASE64"
    +      },
    +      body = ltn12.source.chain(
    +        ltn12.source.file(io.open("image.png", "rb")),
    +        ltn12.filter.chain(
    +          mime.encode("base64"),
    +          mime.wrap()
    +        )
    +      )
    +    },
    +    epilogue = "This might also show up, but after the attachments"
    +  }
    +}
    +
    +-- finally send it
    +r, e = smtp.send{
    +    from = "<sicrano@example.com>",
    +    rcpt = "<fulano@example.com>",
    +    source = source,
    +}
    +
    + +

    @@ -275,123 +393,6 @@ r, e = smtp.send{ } - - -

    -smtp.message(mesgt) -

    - -

    -Returns a simple -LTN12 source that sends an SMTP message body, possibly multipart (arbitrarily deep). -

    - -

    -The only parameter of the function is a table describing the message. -Mesgt has the following form (notice the recursive structure): -

    - -
    - - -
    -mesgt = {
    -  headers = header-table,
    -  body = LTN12 source or string or -multipart-mesgt
    -}

    -multipart-mesgt = {
    -  [preamble = string,]
    -  [1] = mesgt,
    -  [2] = mesgt,
    -  ...
    -  [n] = mesgt,
    -  [epilogue = string,]
    -}
    -
    -
    - -

    -For a simple message, all that is needed is a set of headers -and the body. The message body can be given as a string -or as a simple -LTN12 -source. For multipart messages, the body is a table that -recursively defines each part as an independent message, plus an optional -preamble and epilogue. -

    - -

    -The function returns a simple -LTN12 -source that produces the -message contents as defined by mesgt, chunk by chunk. -Hopefully, the following -example will make things clear. When in doubt, refer to the appropriate RFC -as listed in the introduction.

    - -
    --- load the smtp support and its friends
    -local smtp = require("socket.smtp")
    -local mime = require("mime")
    -local ltn12 = require("ltn12")
    -
    --- creates a source to send a message with two parts. The first part is 
    --- plain text, the second part is a PNG image, encoded as base64.
    -source = smtp.message{
    -  headers = {
    -     -- Remember that headers are *ignored* by smtp.send. 
    -     from = "Sicrano de Oliveira <sicrano@example.com>",
    -     to = "Fulano da Silva <fulano@example.com>",
    -     subject = "Here is a message with attachments"
    -  },
    -  body = {
    -    preamble = "If your client doesn't understand attachments, \r\n" ..
    -               "it will still display the preamble and the epilogue.\r\n" ..
    -               "Preamble will probably appear even in a MIME enabled client.",
    -    -- first part: no headers means plain text, us-ascii.
    -    -- The mime.eol low-level filter normalizes end-of-line markers.
    -    [1] = { 
    -      body = mime.eol(0, [[
    -        Lines in a message body should always end with CRLF. 
    -        The smtp module will *NOT* perform translation. However, the 
    -        send function *DOES* perform SMTP stuffing, whereas the message
    -        function does *NOT*.
    -      ]])
    -    },
    -    -- second part: headers describe content to be a png image, 
    -    -- sent under the base64 transfer content encoding.
    -    -- notice that nothing happens until the message is actually sent. 
    -    -- small chunks are loaded into memory right before transmission and 
    -    -- translation happens on the fly.
    -    [2] = { 
    -      headers = {
    -        ["content-type"] = 'image/png; name="image.png"',
    -        ["content-disposition"] = 'attachment; filename="image.png"',
    -        ["content-description"] = 'a beautiful image',
    -        ["content-transfer-encoding"] = "BASE64"
    -      },
    -      body = ltn12.source.chain(
    -        ltn12.source.file(io.open("image.png", "rb")),
    -        ltn12.filter.chain(
    -          mime.encode("base64"),
    -          mime.wrap()
    -        )
    -      )
    -    },
    -    epilogue = "This might also show up, but after the attachments"
    -  }
    -}
    -
    --- finally send it
    -r, e = smtp.send{
    -    from = "<sicrano@example.com>",
    -    rcpt = "<fulano@example.com>",
    -    source = source,
    -}
    -
    -
  • 'tcp-keepintvl': value for TCP_KEEPINTVL Linux only!!
  • +
  • 'tcp-fastopen': value for TCP_FASTOPEN Linux only!!
  • + +
  • 'tcp-fastopen-connect': value for TCP_FASTOPEN_CONNECT Linux only!!
  • +
  • 'ipv6-v6only': Setting this option to true restricts an inet6 socket to sending and receiving only IPv6 packets.
  • diff --git a/src/options.c b/src/options.c index 2b53c67..51ea351 100644 --- a/src/options.c +++ b/src/options.c @@ -190,6 +190,22 @@ int opt_set_send_buf_size(lua_State *L, p_socket ps) return opt_setint(L, ps, SOL_SOCKET, SO_SNDBUF); } +// /*------------------------------------------------------*/ + +#ifdef TCP_FASTOPEN +int opt_set_tcp_fastopen(lua_State *L, p_socket ps) +{ + return opt_setint(L, ps, IPPROTO_TCP, TCP_FASTOPEN); +} +#endif + +#ifdef TCP_FASTOPEN_CONNECT +int opt_set_tcp_fastopen_connect(lua_State *L, p_socket ps) +{ + return opt_setint(L, ps, IPPROTO_TCP, TCP_FASTOPEN_CONNECT); +} +#endif + /*------------------------------------------------------*/ int opt_set_ip6_unicast_hops(lua_State *L, p_socket ps) { diff --git a/src/options.h b/src/options.h index 41f7337..a4d5d75 100644 --- a/src/options.h +++ b/src/options.h @@ -64,6 +64,13 @@ int opt_get_recv_buf_size(lua_State *L, p_socket ps); int opt_set_send_buf_size(lua_State *L, p_socket ps); int opt_get_send_buf_size(lua_State *L, p_socket ps); +#ifdef TCP_FASTOPEN +int opt_set_tcp_fastopen(lua_State *L, p_socket ps); +#endif +#ifdef TCP_FASTOPEN_CONNECT +int opt_set_tcp_fastopen_connect(lua_State *L, p_socket ps); +#endif + int opt_set_ip6_unicast_hops(lua_State *L, p_socket ps); int opt_get_ip6_unicast_hops(lua_State *L, p_socket ps); diff --git a/src/tcp.c b/src/tcp.c index 5876bfb..e24cb0c 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -109,6 +109,12 @@ static t_opt optset[] = { {"linger", opt_set_linger}, {"recv-buffer-size", opt_set_recv_buf_size}, {"send-buffer-size", opt_set_send_buf_size}, +#ifdef TCP_FASTOPEN + {"tcp-fastopen", opt_set_tcp_fastopen}, +#endif +#ifdef TCP_FASTOPEN_CONNECT + {"tcp-fastopen-connect", opt_set_tcp_fastopen_connect}, +#endif {NULL, NULL} }; -- cgit v1.2.3-55-g6feb From d1ad8160cba9e504c9d17665492044a93efdc3ab Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 27 Jul 2022 08:40:18 +0200 Subject: feat(tcp): Add support for TCP Defer Accept This makes it so that a listening socket does not become readable for accept() until a connection has been fully established *and* started sending something, thus the program doesn't have to wait for the first data. This only makes sense for client-speaks-first protocols. Co-authored-by: Caleb Maclennan --- docs/tcp.html | 2 ++ src/options.c | 9 +++++++++ src/options.h | 4 ++++ src/tcp.c | 3 +++ 4 files changed, 18 insertions(+) (limited to 'src/tcp.c') diff --git a/docs/tcp.html b/docs/tcp.html index f15196c..a26228d 100644 --- a/docs/tcp.html +++ b/docs/tcp.html @@ -485,6 +485,8 @@ disables the Nagle's algorithm for the connection;
  • 'tcp-keepintvl': value for TCP_KEEPINTVL Linux only!!
  • +
  • 'tcp-defer-accept': value for TCP_DEFER_ACCEPT Linux only!!
  • +
  • 'tcp-fastopen': value for TCP_FASTOPEN Linux only!!
  • 'tcp-fastopen-connect': value for TCP_FASTOPEN_CONNECT Linux only!!
  • diff --git a/src/options.c b/src/options.c index 51ea351..3280c51 100644 --- a/src/options.c +++ b/src/options.c @@ -206,6 +206,15 @@ int opt_set_tcp_fastopen_connect(lua_State *L, p_socket ps) } #endif +/*------------------------------------------------------*/ + +#ifdef TCP_DEFER_ACCEPT +int opt_set_tcp_defer_accept(lua_State *L, p_socket ps) +{ + return opt_setint(L, ps, IPPROTO_TCP, TCP_DEFER_ACCEPT); +} +#endif + /*------------------------------------------------------*/ int opt_set_ip6_unicast_hops(lua_State *L, p_socket ps) { diff --git a/src/options.h b/src/options.h index a4d5d75..456eeb5 100644 --- a/src/options.h +++ b/src/options.h @@ -49,6 +49,10 @@ int opt_set_tcp_keepintvl(lua_State *L, p_socket ps); int opt_get_tcp_keepintvl(lua_State *L, p_socket ps); #endif +#ifdef TCP_DEFER_ACCEPT +int opt_set_tcp_defer_accept(lua_State *L, p_socket ps); +#endif + int opt_set_keepalive(lua_State *L, p_socket ps); int opt_get_keepalive(lua_State *L, p_socket ps); diff --git a/src/tcp.c b/src/tcp.c index e24cb0c..e84db84 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -109,6 +109,9 @@ static t_opt optset[] = { {"linger", opt_set_linger}, {"recv-buffer-size", opt_set_recv_buf_size}, {"send-buffer-size", opt_set_send_buf_size}, +#ifdef TCP_DEFER_ACCEPT + {"tcp-defer-accept", opt_set_tcp_defer_accept}, +#endif #ifdef TCP_FASTOPEN {"tcp-fastopen", opt_set_tcp_fastopen}, #endif -- cgit v1.2.3-55-g6feb From f741a88b80ffcf4de65b91ff82fc9f7865cbad0e Mon Sep 17 00:00:00 2001 From: Leso_KN Date: Mon, 23 Oct 2023 20:27:01 +0200 Subject: feat(tcp): Add 'bindtodevice' option (#408) --- src/options.c | 27 +++++++++++++++++++++++++++ src/options.h | 3 +++ src/tcp.c | 2 ++ 3 files changed, 32 insertions(+) (limited to 'src/tcp.c') diff --git a/src/options.c b/src/options.c index 657947c..3856797 100644 --- a/src/options.c +++ b/src/options.c @@ -54,6 +54,33 @@ int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps) return opt->func(L, ps); } +/*------------------------------------------------------*/ +/* binds socket to network interface */ +int opt_set_bindtodevice(lua_State *L, p_socket ps) +{ +#ifdef __APPLE__ + return luaL_error(L, "SO_BINDTODEVICE is not supported on this operating system"); +#else + const char *dev = luaL_checkstring(L, 3); + return opt_set(L, ps, SOL_SOCKET, SO_BINDTODEVICE, (char*)dev, strlen(dev)+1); +#endif +} + +int opt_get_bindtodevice(lua_State *L, p_socket ps) +{ +#ifdef __APPLE__ + return luaL_error(L, "SO_BINDTODEVICE is not supported on this operating system"); +#else + char dev[IFNAMSIZ]; + int len = sizeof(dev); + int err = opt_get(L, ps, SOL_SOCKET, SO_BINDTODEVICE, &dev, &len); + if (err) + return err; + lua_pushstring(L, dev); + return 1; +#endif +} + /*------------------------------------------------------*/ /* enables reuse of local address */ int opt_set_reuseaddr(lua_State *L, p_socket ps) diff --git a/src/options.h b/src/options.h index 456eeb5..26d6f02 100644 --- a/src/options.h +++ b/src/options.h @@ -53,6 +53,9 @@ int opt_get_tcp_keepintvl(lua_State *L, p_socket ps); int opt_set_tcp_defer_accept(lua_State *L, p_socket ps); #endif +int opt_set_bindtodevice(lua_State *L, p_socket ps); +int opt_get_bindtodevice(lua_State *L, p_socket ps); + int opt_set_keepalive(lua_State *L, p_socket ps); int opt_get_keepalive(lua_State *L, p_socket ps); diff --git a/src/tcp.c b/src/tcp.c index e84db84..f001206 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -71,6 +71,7 @@ static luaL_Reg tcp_methods[] = { /* socket option handlers */ static t_opt optget[] = { + {"bindtodevice", opt_get_bindtodevice}, {"keepalive", opt_get_keepalive}, {"reuseaddr", opt_get_reuseaddr}, {"reuseport", opt_get_reuseport}, @@ -92,6 +93,7 @@ static t_opt optget[] = { }; static t_opt optset[] = { + {"bindtodevice", opt_set_bindtodevice}, {"keepalive", opt_set_keepalive}, {"reuseaddr", opt_set_reuseaddr}, {"reuseport", opt_set_reuseport}, -- cgit v1.2.3-55-g6feb