flomesh-io / pipy

Pipy is a programmable proxy for the cloud, edge and IoT.
https://flomesh.io/pipy
Other
743 stars 70 forks source link

`bind` override `socket.setRawOption` #188

Open yyk808 opened 3 days ago

yyk808 commented 3 days ago

TLDR

// pipy this_file.js --reuse-port

pipy().task().onStart(new Message('Turn around')).connect('127.0.0.1:8000', {
  bind: '127.0.0.1:1234',
  onState: (conn) => {
    if(conn.state === 'open') {
      conn.socket.setRawOption(1, 15, new Data([1]))
    }
  },
}).listen('127.0.0.1:1234').print()

The code above won't work correctly.

Reproduce

  1. Setting up a server returning message.

    pipy -e 'pipy().listen("127.0.0.1:8000").print().connect("127.0.0.1:1234")'
  2. Using code in the tldr to get error log like:

    ❯ pipy error.js --reuse-port
    2024-06-27 21:49:31.069 [INF] [config]
    2024-06-27 21:49:31.069 [INF] [config] Module /error.js
    2024-06-27 21:49:31.069 [INF] [config] ================
    2024-06-27 21:49:31.069 [INF] [config]
    2024-06-27 21:49:31.069 [INF] [config]  [Listen on 1234 at 127.0.0.1]
    2024-06-27 21:49:31.069 [INF] [config]  ----->|
    2024-06-27 21:49:31.069 [INF] [config]        |
    2024-06-27 21:49:31.069 [INF] [config]       print -->|
    2024-06-27 21:49:31.069 [INF] [config]                |
    2024-06-27 21:49:31.069 [INF] [config]  <-------------|
    2024-06-27 21:49:31.069 [INF] [config]  
    2024-06-27 21:49:31.069 [INF] [config]  [Task #1 ()]
    2024-06-27 21:49:31.069 [INF] [config]  ----->|
    2024-06-27 21:49:31.069 [INF] [config]        |
    2024-06-27 21:49:31.069 [INF] [config]       connect -->|
    2024-06-27 21:49:31.069 [INF] [config]                  |
    2024-06-27 21:49:31.069 [INF] [config]  <---------------|
    2024-06-27 21:49:31.069 [INF] [config]  
    2024-06-27 21:49:31.069 [INF] [listener] Listening on TCP port 1234 at 127.0.0.1
    2024-06-27 21:49:31.069 [ERR] connect() at line 1 column 58 in /error.js: bind: Address already in use
    2024-06-27 21:49:31.069 [ERR] connect() at line 1 column 58 in /error.js: bind: Address already in use
    2024-06-27 21:49:31.069 [ERR] connect() at line 1 column 58 in /error.js: bind: Address already in use
    ^C2024-06-27 21:49:32.175 [INF] [shutdown] Shutting down...
    2024-06-27 21:49:32.175 [INF] [shutdown] Waiting for workers to drain...
    2024-06-27 21:49:32.175 [INF] [listener] Stopped listening on TCP port 1234 at 127.0.0.1
  3. Also, I've made a python equivalent. If everything works fine in pipy, the pjs code should act just like this.

    
    import socket

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)

BIND = 1234 TARGET = 8000

try: client.bind(('127.0.0.1', BIND)) server.bind(('127.0.0.1', BIND))

server.listen(1)
client.connect(('127.0.0.1', TARGET))

client.sendall(b'Turn around')

s, _ = server.accept()
data = s.recv(16)
s.close()

print(data.decode())

finally: client.close() server.close()



## Reason
I tried to add a print in `src/socket.cpp` line 885 where we define `setRawOption`, it will only be called when not set `bind` option.
So it comes out that `bind` will override `setRawOption`.