fix: problem that not switch to tcp if udp is blocked

This commit is contained in:
mzz2017 2023-02-09 13:27:59 +08:00
parent d364efc5c7
commit 2107aead00
5 changed files with 28 additions and 27 deletions

View File

@ -9,12 +9,15 @@ import (
"net"
)
type blockDialer struct{}
type blockDialer struct {
DialCallback func()
}
func (*blockDialer) Dial(network string, addr string) (c net.Conn, err error) {
func (d *blockDialer) Dial(network string, addr string) (c net.Conn, err error) {
d.DialCallback()
return nil, net.ErrClosed
}
func NewBlockDialer(option *GlobalOption) *Dialer {
return NewDialer(&blockDialer{}, option, InstanceOption{CheckEnabled: false}, "block", "block", "")
func NewBlockDialer(option *GlobalOption, dialCallback func()) *Dialer {
return NewDialer(&blockDialer{DialCallback: dialCallback}, option, InstanceOption{CheckEnabled: false}, "block", "block", "")
}

View File

@ -65,10 +65,14 @@ func NewDialerGroup(option *dialer.GlobalOption, name string, dialers []*dialer.
}
return &DialerGroup{
log: log,
Name: name,
Dialers: dialers,
block: dialer.NewBlockDialer(option),
log: log,
Name: name,
Dialers: dialers,
block: dialer.NewBlockDialer(option, func() {
log.WithFields(logrus.Fields{
"group": name,
}).Warnf("No alive dialer for given nerwork in DialerGroup, use \"block\".")
}),
AliveTcp4DialerSet: aliveTcp4DialerSet,
AliveTcp6DialerSet: aliveTcp6DialerSet,
AliveUdp4DialerSet: aliveUdp4DialerSet,
@ -125,11 +129,7 @@ func (g *DialerGroup) Select(l4proto consts.L4ProtoStr, ipversion consts.IpVersi
d := a.GetRand()
if d == nil {
// No alive dialer.
g.log.WithFields(logrus.Fields{
"network": string(l4proto) + string(ipversion),
"group": g.Name,
}).Warnf("No alive dialer in DialerGroup, use \"block\".")
return g.block, 0, nil
return g.block, time.Hour, nil
}
return d, 0, nil
@ -143,11 +143,7 @@ func (g *DialerGroup) Select(l4proto consts.L4ProtoStr, ipversion consts.IpVersi
d, latency := a.GetMinLatency()
if d == nil {
// No alive dialer.
g.log.WithFields(logrus.Fields{
"network": string(l4proto) + string(ipversion),
"group": g.Name,
}).Warnf("No alive dialer in DialerGroup, use \"block\".")
return g.block, 0, nil
return g.block, time.Hour, nil
}
return d, latency, nil

View File

@ -6,7 +6,6 @@
package control
import (
"fmt"
"github.com/cilium/ebpf"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
@ -27,7 +26,7 @@ func (c *ControlPlaneCore) OutboundAliveChangeCallback(outbound uint8) func(aliv
return func(alive bool, l4proto uint8, ipversion uint8) {
c.log.WithFields(logrus.Fields{
"alive": alive,
"network": fmt.Sprintf("%v+%v", FormatL4Proto(l4proto), ipversion),
"network": FormatL4Proto(l4proto) + strconv.Itoa(int(ipversion)),
"outbound_id": outbound,
}).Warnf("Outbound alive state changed, notify the kernel program.")

View File

@ -215,7 +215,7 @@ func NewControlPlane(
FixedIndex: 0,
}, core.OutboundAliveChangeCallback(0)),
outbound.NewDialerGroup(option, consts.OutboundBlock.String(),
[]*dialer.Dialer{dialer.NewBlockDialer(option)},
[]*dialer.Dialer{dialer.NewBlockDialer(option, func() { /*Dialer Outbound*/ })},
outbound.DialerSelectionPolicy{
Policy: consts.DialerSelectionPolicy_Fixed,
FixedIndex: 0,

View File

@ -1329,8 +1329,9 @@ new_connection:
q.l4proto = l4proto;
__u32 *alive;
alive = bpf_map_lookup_elem(&outbound_connectivity_map, &q);
if (alive && *alive == 0) {
// Outbound is not alive.
if (alive && *alive == 0 &&
!(l4proto == IPPROTO_UDP && tuples.dst.port == bpf_htons(53))) {
// Outbound is not alive. Dns is an exception.
goto block;
}
@ -1646,8 +1647,9 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
q.l4proto = l4proto;
__u32 *alive;
alive = bpf_map_lookup_elem(&outbound_connectivity_map, &q);
if (alive && *alive == 0) {
// Outbound is not alive.
if (alive && *alive == 0 &&
!(l4proto == IPPROTO_UDP && tuples.dst.port == bpf_htons(53))) {
// Outbound is not alive. Dns is an exception.
return TC_ACT_SHOT;
}
@ -1727,8 +1729,9 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
q.l4proto = l4proto;
__u32 *alive;
alive = bpf_map_lookup_elem(&outbound_connectivity_map, &q);
if (alive && *alive == 0) {
// Outbound is not alive.
if (alive && *alive == 0 &&
!(l4proto == IPPROTO_UDP && tuples.dst.port == bpf_htons(53))) {
// Outbound is not alive. Dns is an exception.
return TC_ACT_SHOT;
}