Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setoption failing in 3.0.0 (works with the old RC) #371

Open
Tieske opened this issue Mar 28, 2022 · 5 comments
Open

setoption failing in 3.0.0 (works with the old RC) #371

Tieske opened this issue Mar 28, 2022 · 5 comments
Labels

Comments

@Tieske
Copy link
Member

Tieske commented Mar 28, 2022

Downstream issue: Kong/kong#8590

To reproduce run this docker command:

docker run -it --rm ubuntu /bin/bash

Once in the shell create a Lua file called test.lua;

local socket = require "socket"
local server = assert(socket.tcp())
server:settimeout(60)
assert(server:setoption("reuseaddr", true))
assert(server:bind("*", 14123))

Execute the following commands:

apt update
apt install luarocks
luarocks install luasocket
lua test.lua

Output:

root@3c61aa79bab9:/# lua test.lua
lua: test.lua:4: setsockopt failed
stack traceback:
	[C]: in function 'assert'
	test.lua:4: in main chunk
	[C]: ?
root@3c61aa79bab9:/#
@Tieske
Copy link
Member Author

Tieske commented Mar 28, 2022

This seems to work:

local socket = require "socket"
local server = assert(socket.tcp())
server:settimeout(60)
assert(server:bind("*", 14123))	-- switch position between 'bind' and 'setoption'
assert(server:setoption("reuseaddr", true))

@alerque
Copy link
Member

alerque commented Mar 28, 2022

This seems to bisect to 77bba62.

@alerque alerque added the bug label Mar 28, 2022
@Tieske
Copy link
Member Author

Tieske commented Mar 28, 2022

adding to my previous comment: using setoption after bind doesn't make sense, because bind would already have failed if it was in use.

@Tieske
Copy link
Member Author

Tieske commented Mar 28, 2022

This looks nasty on a first glance, as per the docs:

  • internal socket is invalid until ipv4 or ipv6 is selected, setoption fails while in this state
  • ip-family is selected upon calling bind
  • SO_REUSEADDR option should be set before calling bind

So there's a catch 22 it seems.

Any ideas @diegonehab @Florob (pinging because the referenced commit above mentions you)

@Florob
Copy link
Contributor

Florob commented Mar 28, 2022

I've been out of the loop for most things Lua for a few years, so not sure how much I can help here.

Judging by the discussion in #147 and looking at inet_trybind() the problem is probably yet worse. inet_trybind() will create multiple new sockets while attempting to bind to addresses resolved by getaddrinfo. So even if we could set the option before calling bind() it would potentially get lost. This is part of why we deemed starting out with an invalid socket acceptable.

A pragmatic approach might be to add an optional reuseaddr parameter to bind(). When true the implementation would set SO_REUSEADDR on the sockets it creates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

3 participants