fix(dialer): skip SO_BINDTODEVICE for empty-addr UDP relay sockets
Removes bindDevice from dialOnce's UDP empty-addr path. For relay/listener UDP sockets, the ListenUDP laddr binding already pins the source IP correctly. The additional SO_BINDTODEVICE forced all outbound datagrams through the named interface, which conflicts with the kernel routing table for unconnected UDP sockets and causes silent packet drops — breaking SOCKS5 UDP associate when interface is configured. Fixes go-gost/gost#287
This commit is contained in:
@@ -123,11 +123,12 @@ func (d *Dialer) dialOnce(ctx context.Context, network, addr, ifceName string, i
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = sc.Control(func(fd uintptr) {
|
err = sc.Control(func(fd uintptr) {
|
||||||
if ifceName != "" {
|
// NOTE: bindDevice is intentionally skipped for empty-addr UDP
|
||||||
if err := bindDevice(network, addr, fd, ifceName); err != nil {
|
// (relay/listener sockets). The ListenUDP laddr binding above
|
||||||
log.Warnf("bind device: %v", err)
|
// is sufficient to pin the source IP. SO_BINDTODEVICE would
|
||||||
}
|
// force all outbound datagrams through the named interface,
|
||||||
}
|
// which may conflict with the kernel routing table and cause
|
||||||
|
// silent packet drops — breaking UDP associate (issue #287).
|
||||||
if d.Mark != 0 {
|
if d.Mark != 0 {
|
||||||
if err := setMark(fd, d.Mark); err != nil {
|
if err := setMark(fd, d.Mark); err != nil {
|
||||||
log.Warnf("set mark: %v", err)
|
log.Warnf("set mark: %v", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user