Rodney Lott
Rodney Lott

Reputation: 13

Is the ngx.socket.tcp() call limited in any way when called from an nginx location context?

I'm very new to using the local sock = ngx.socket.tcp() call that is provided by the nginx lua packages provided on Ubuntu Noble (i.e. the libnginx-mod-http-lua package). I've been able to get some success in opening a socket and writing out some data. But, based on my tcpdump analysis and other cues, the sock:send() operation works but I don't get any data back. My current theory is that nginx somehow prevents the ACK from the sock:connect() from being received by the lua block.

In order to simplify things, I decided to reproduce this simple example to make sure that I'm doing things correctly. When I make up my own version of this, it hangs on the receive() call.

Here is my setup:

Here's the code snippets I'm using and their output:

nginx test location:

location /foo {
    content_by_lua_block {
        local tcp=ngx.socket.tcp()
        ngx.say(ngx.now())
        ngx.flush()
        tcp:connect("127.0.0.1", 8000)
        ngx.say("connect() did not block")
        ngx.flush()
        local data, err = tcp:receive(1)
        ngx.say("receive() did not block")
        ngx.say(err)
        ngx.flush()
        ngx.update_time()
        ngx.say(ngx.now())
        ngx.flush()
    }
}

curl invocation (which I Ctrl+C b/c it hangs):

rlott@1022rdnote04:~/testing$ curl -k https://192.168.56.220/foo
1740693455.69
connect() did not block
^C
rlott@1022rdnote04:~/testing$

nc running on port 8000 (doing nothing):

etservice@noble:~$ nc -l 8000 -k

Errors I see in /var/log/nginx/error.log (eventually):

2025/02/27 16:58:35 [error] 608728#608728: *101 lua tcp socket read timed out, client: 192.168.56.1, server: , request: "GET /foo HTTP/1.1", host: "192.168.56.220"
2025/02/27 16:58:35 [info] 608728#608728: *101 client 192.168.56.1 closed keepalive connection

So, the $1M question is what is the secret to using nginx.socket.tcp() successfully in this way?

Again, I did another example where I sent a JSON-RPC message to one of my services and tcpdump shows me that the data got there, but that it hangs on the sock:receive(). The only difference between my message and a bonafide client sending the same message seems to be something having to do with the "Conversation completeness" (taken from my Wireshark analysis). In the Wireshark analysis, the only 2 things that I could see that were different were:

  1. My message didn have a TCP FIN flag set
  2. The bonafide client's JSON-RPC message had a larger data size than mine.

So, I'm kinda stumped. Any insight would be appreciated.

Upvotes: 0

Views: 23

Answers (0)

Related Questions