shadowsocks / shadowsocks-rust

A Rust port of shadowsocks
https://shadowsocks.org/
MIT License
8.37k stars 1.15k forks source link

ssserver exits with UDP unable to bind port error #294

Closed made-by-love closed 3 months ago

made-by-love commented 4 years ago

Error log:

> > 2020-09-11T09:08:26.795-04:00 TRACE [shadowsocks::relay::udprelay::server] received UDP packet from 124.64.17.102:36465, length 1405 bytes
> > 2020-09-11T09:08:26.815-04:00 ERROR [shadowsocks::relay::udprelay::server] failed to create UDP association, Address already in use (os error 98)
> > 2020-09-11T09:08:26.815-04:00 ERROR [shadowsocks::relay::udprelay::server] one of UDP servers exited unexpectly, result: Err(Os { code: 98, kind: AddrInUse, message: "Address already in use" })
> > 2020-09-11T09:08:26.815-04:00 ERROR [shadowsocks::relay::server] one of servers exited unexpectly, result: Err(Custom {
> > kind: Other, error: "err udp server exited unexpectly" })
> > thread 'main' panicked at 'aborted with server exited unexpectly', src/bin/server.rs:2020-09-11T09:08:26.816-04:00 DEBUG [trust_dns_proto::xfer::dns_exchange] io_stream is done, shutting down
> > 216:21
> > 2020-09-11T09:08:26.816-04:00 DEBUG [trust_dns_proto::xfer::dns_exchange] io_stream is done, shutting down
> > note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
> > 2020-09-11T09:08:26.816-04:00 DEBUG [trust_dns_proto::xfer::dns_exchange] io_stream is done, shutting down
> 

The server info:

CPU: Intel(R) Xeon(R) CPU E5-2650 v2 @ 2.60GHz x2 Mem:

cat /proc/meminfo
MemTotal:       131992960 kB
MemFree:        118176972 kB
MemAvailable:   123668772 kB

UDP sockets:

netstat -lu |wc -l
26529

limits: cat /etc/security/limits.conf

*               soft    nofile           1048576
*               hard    nofile           1048576
root            soft    nofile           1048576
root            hard    nofile           1048576

The system has enough resources to create UDP sockets, it should not fail to bind a new UDP port, if fail to bind, the ssserver should not exit either, it's better to just bypass the error

zonyitoo commented 4 years ago

The system has enough resources to create UDP sockets, it should not fail to bind a new UDP port,

Your error is: Err(Os { code: 98, kind: AddrInUse, message: "Address already in use" }), which shouldn't be caused by fd excausted. In this case, I think that you must have specified the local_address and local_port in your configuration.

This is a BUG. UDP association shouldn't use local_address and local_port, which are only for TCP sockets.

Released in v1.8.18.

if fail to bind, the ssserver should not exit either, it's better to just bypass the error

Update to >= v1.8.17: https://github.com/shadowsocks/shadowsocks-rust/releases/tag/v1.8.17

made-by-love commented 4 years ago

This is a BUG. UDP association shouldn't use local_address and local_port, which are only for TCP sockets. This fix will cause issues on server with multiple IP addresses. The UDP association should use local_address and port 0 to bind UDP sockets, or else the UDP association may use a different IP address from TCP sockets. The will cause issues for some applications, such as whatsapp/messenger Voice/Video calls using UDP.

In this case, I think that you must have specified the local_address and local_port in your configuration. No, I didn't specified local_address nor local_port in config.

Here is the config:

 cat ssrconfig.json
{
    "server":"0.0.0.0",
    "server_port":4738,
    "password":".......",
    "timeout":300,
    "method":"chacha20-ietf-poly1305",
    "fast_open": true,
    "bind_remote": "local",
    "dns_server":["127.0.0.1"],
    "tunnel_remote":"127.0.0.1",
    "tunnel_remote_port":53,
    "tunnel_port":53,
    "tunnel_dns":true,
    "workers": 33
}
zonyitoo commented 4 years ago

Please try again with the latest release.

made-by-love commented 4 years ago

Hello, tested with the latest release, it still has unable binding issue, but will try again and bind successfully.

2020-09-16T06:31:29.730-04:00 DEBUG [trust_dns_proto::udp::udp_stream] unable to bind port, attempt: 0: Address already in use (os error 98)
2020-09-16T06:31:29.731-04:00 DEBUG [trust_dns_proto::udp::udp_stream] unable to bind port, attempt: 1: Address already in use (os error 98)
2020-09-16T06:31:29.731-04:00 DEBUG [trust_dns_proto::udp::udp_stream] unable to bind port, attempt: 2: Address already in use (os error 98)
2020-09-16T06:31:29.731-04:00 DEBUG [trust_dns_proto::udp::udp_stream] unable to bind port, attempt: 3: Address already in use (os error 98)
2020-09-16T06:31:29.731-04:00 DEBUG [trust_dns_proto::udp::udp_stream] created socket successfully
2020-09-16T06:31:29.731-04:00 DEBUG [trust_dns_proto::udp::udp_stream] created socket successfully
zonyitoo commented 4 years ago

trust_dns_proto::udp::udp_stream

This error was reported by the DNS client library. So it is not the same error as this issue was originally created.

Since the UDP socket was finally created after retry in 1ms, it shouldn't be an issue, right?

made-by-love commented 4 years ago

Yes, it's working now, but I think it's a bug of the DNS client library. It should be fixed.

made-by-love commented 4 years ago

Since the UDP socket was finally created after retry in 1ms, it shouldn't be an issue, right?

And I think the UDP relay issue is not resolved, but just bypassed to create UDP association. In the fix, it just returns instead of exiting. It should attempt to recreate the UDP association like the DNS client library does.

zonyitoo commented 4 years ago

Since the UDP socket was finally created after retry in 1ms, it shouldn't be an issue, right?

And I think the UDP relay issue is not resolved, but just bypassed to create UDP association. In the fix, it just returns instead of exiting. It should attempt to recreate the UDP association like the DNS client library does.

It will re-create the association when it receives another packet.

made-by-love commented 4 years ago

Since the UDP socket was finally created after retry in 1ms, it shouldn't be an issue, right?

And I think the UDP relay issue is not resolved, but just bypassed to create UDP association. In the fix, it just returns instead of exiting. It should attempt to recreate the UDP association like the DNS client library does.

It will re-create the association when it receives another packet.

Then the failed packet will be dropped... Even it's UDP, it's a bad experience as the system has enough resources.

zonyitoo commented 4 years ago

Since the UDP socket was finally created after retry in 1ms, it shouldn't be an issue, right?

And I think the UDP relay issue is not resolved, but just bypassed to create UDP association. In the fix, it just returns instead of exiting. It should attempt to recreate the UDP association like the DNS client library does.

It will re-create the association when it receives another packet.

Then the failed packet will be dropped... Even it's UDP, it's a bad experience as the system has enough resources.

Since that BUG is fixed, associations creation won't be failed if system has enough ports.

made-by-love commented 4 years ago

Since that BUG is fixed, associations creation won't be failed if system has enough ports.

No, it's not fixed, after running for about 10 hours, the DNS totally failed, i can se only UDP associations(telegram traffic), no tcp traffic that needs DNS first.

The DNS client must have some deadly issue.

zonyitoo commented 4 years ago

It seems that there is something special in your running environment. I haven't encountered anything like this after running several days.

made-by-love commented 3 years ago

Yes, changed something, I use dnsmasq as dns proxy on server.

paracaidas2003 commented 1 year ago

cargo clean