diff --git a/common/consts/ebpf.go b/common/consts/ebpf.go index 23e1629..7b04dad 100644 --- a/common/consts/ebpf.go +++ b/common/consts/ebpf.go @@ -165,12 +165,6 @@ const ( type LanWanFlag uint8 -const ( - LanWanFlag_IsWan LanWanFlag = iota - LanWanFlag_IsLan - LanWanFlag_NotApplicable -) - const ( LinkHdrLen_None uint32 = 0 LinkHdrLen_Ethernet uint32 = 14 diff --git a/control/addr.go b/control/addr.go index 4274439..1bccfbc 100644 --- a/control/addr.go +++ b/control/addr.go @@ -9,12 +9,10 @@ import ( "net" "net/netip" "strconv" - - "github.com/daeuniverse/dae/common/consts" ) -func RefineSourceToShow(src netip.AddrPort, dst netip.Addr, lanWanFlag consts.LanWanFlag) (srcToShow string) { - if lanWanFlag == consts.LanWanFlag_IsWan || src.Addr() == dst { +func RefineSourceToShow(src netip.AddrPort, dst netip.Addr) (srcToShow string) { + if src.Addr() == dst { // If nothing else, this means this packet is sent from localhost. return net.JoinHostPort("localhost", strconv.Itoa(int(src.Port()))) } else { diff --git a/control/control.go b/control/control.go index c27498e..93211c8 100644 --- a/control/control.go +++ b/control/control.go @@ -5,4 +5,4 @@ package control -//go:generate go run -mod=mod github.com/cilium/ebpf/cmd/bpf2go -cc "$BPF_CLANG" "$BPF_STRIP_FLAG" -cflags "$BPF_CFLAGS" -target "$BPF_TARGET" -type dst_routing_result bpf kern/tproxy.c -- -I./headers +//go:generate go run -mod=mod github.com/cilium/ebpf/cmd/bpf2go -cc "$BPF_CLANG" "$BPF_STRIP_FLAG" -cflags "$BPF_CFLAGS" -target "$BPF_TARGET" bpf kern/tproxy.c -- -I./headers diff --git a/control/control_plane_core.go b/control/control_plane_core.go index 5c3990b..6becce7 100644 --- a/control/control_plane_core.go +++ b/control/control_plane_core.go @@ -510,38 +510,6 @@ func (c *controlPlaneCore) _bindLan(ifname string) error { } return nil }) - - // Insert filters. - filterEgress := &netlink.BpfFilter{ - FilterAttrs: netlink.FilterAttrs{ - LinkIndex: link.Attrs().Index, - Parent: netlink.HANDLE_MIN_EGRESS, - Handle: netlink.MakeHandle(0x2023, 0b010+uint16(c.flip)), - Protocol: unix.ETH_P_ALL, - // Priority should be front of WAN's - Priority: 1, - }, - Fd: c.bpf.bpfPrograms.TproxyLanEgress.FD(), - Name: consts.AppName + "_lan_egress", - DirectAction: true, - } - // Remove and add. - _ = netlink.FilterDel(filterEgress) - if !c.isReload { - // Clean up thoroughly. - filterEgressFlipped := deepcopy.Copy(filterEgress).(*netlink.BpfFilter) - filterEgressFlipped.FilterAttrs.Handle ^= 1 - _ = netlink.FilterDel(filterEgressFlipped) - } - if err := netlink.FilterAdd(filterEgress); err != nil { - return fmt.Errorf("cannot attach ebpf object to filter egress: %w", err) - } - c.deferFuncs = append(c.deferFuncs, func() error { - if err := netlink.FilterDel(filterEgress); err != nil { - return fmt.Errorf("FilterDel(%v:%v): %w", ifname, filterEgress.Name, err) - } - return nil - }) return nil } diff --git a/control/dns_control.go b/control/dns_control.go index fab4e1d..e1f91fc 100644 --- a/control/dns_control.go +++ b/control/dns_control.go @@ -326,7 +326,6 @@ func (c *DnsController) UpdateDnsCacheTtl(host string, dnsTyp uint16, answers [] } type udpRequest struct { - lanWanFlag consts.LanWanFlag realSrc netip.AddrPort realDst netip.AddrPort src netip.AddrPort @@ -347,7 +346,7 @@ func (c *DnsController) Handle_(dnsMessage *dnsmessage.Msg, req *udpRequest) (er if c.log.IsLevelEnabled(logrus.TraceLevel) && len(dnsMessage.Question) > 0 { q := dnsMessage.Question[0] c.log.Tracef("Received UDP(DNS) %v <-> %v: %v %v", - RefineSourceToShow(req.realSrc, req.realDst.Addr(), req.lanWanFlag), req.realDst.String(), strings.ToLower(q.Name), QtypeToString(q.Qtype), + RefineSourceToShow(req.realSrc, req.realDst.Addr()), req.realDst.String(), strings.ToLower(q.Name), QtypeToString(q.Qtype), ) } @@ -410,7 +409,7 @@ func (c *DnsController) Handle_(dnsMessage *dnsmessage.Msg, req *udpRequest) (er // resp is valid. cache2 := c.LookupDnsRespCache(c.cacheKey(qname, qtype2), true) if c.qtypePrefer == qtype || cache2 == nil || !cache2.IncludeAnyIp() { - return sendPkt(resp, req.realDst, req.realSrc, req.src, req.lConn, req.lanWanFlag) + return sendPkt(resp, req.realDst, req.realSrc, req.src, req.lConn) } else { return c.sendReject_(dnsMessage, req) } @@ -454,14 +453,14 @@ func (c *DnsController) handle_( if resp := c.LookupDnsRespCache_(dnsMessage, cacheKey, false); resp != nil { // Send cache to client directly. if needResp { - if err = sendPkt(resp, req.realDst, req.realSrc, req.src, req.lConn, req.lanWanFlag); err != nil { + if err = sendPkt(resp, req.realDst, req.realSrc, req.src, req.lConn); err != nil { return fmt.Errorf("failed to write cached DNS resp: %w", err) } } if c.log.IsLevelEnabled(logrus.DebugLevel) && len(dnsMessage.Question) > 0 { q := dnsMessage.Question[0] c.log.Debugf("UDP(DNS) %v <-> Cache: %v %v", - RefineSourceToShow(req.realSrc, req.realDst.Addr(), req.lanWanFlag), strings.ToLower(q.Name), QtypeToString(q.Qtype), + RefineSourceToShow(req.realSrc, req.realDst.Addr()), strings.ToLower(q.Name), QtypeToString(q.Qtype), ) } return nil @@ -502,7 +501,7 @@ func (c *DnsController) sendReject_(dnsMessage *dnsmessage.Msg, req *udpRequest) if err != nil { return fmt.Errorf("pack DNS packet: %w", err) } - if err = sendPkt(data, req.realDst, req.realSrc, req.src, req.lConn, req.lanWanFlag); err != nil { + if err = sendPkt(data, req.realDst, req.realSrc, req.src, req.lConn); err != nil { return err } return nil @@ -735,9 +734,9 @@ func (c *DnsController) dialSend(invokingDepth int, req *udpRequest, data []byte } switch upstreamIndex { case consts.DnsResponseOutboundIndex_Accept: - c.log.WithFields(fields).Infof("%v <-> %v", RefineSourceToShow(req.realSrc, req.realDst.Addr(), req.lanWanFlag), RefineAddrPortToShow(dialArgument.bestTarget)) + c.log.WithFields(fields).Infof("%v <-> %v", RefineSourceToShow(req.realSrc, req.realDst.Addr()), RefineAddrPortToShow(dialArgument.bestTarget)) case consts.DnsResponseOutboundIndex_Reject: - c.log.WithFields(fields).Infof("%v -> reject", RefineSourceToShow(req.realSrc, req.realDst.Addr(), req.lanWanFlag)) + c.log.WithFields(fields).Infof("%v -> reject", RefineSourceToShow(req.realSrc, req.realDst.Addr())) default: return fmt.Errorf("unknown upstream: %v", upstreamIndex.String()) } @@ -752,7 +751,7 @@ func (c *DnsController) dialSend(invokingDepth int, req *udpRequest, data []byte if err != nil { return err } - if err = sendPkt(data, req.realDst, req.realSrc, req.src, req.lConn, req.lanWanFlag); err != nil { + if err = sendPkt(data, req.realDst, req.realSrc, req.src, req.lConn); err != nil { return err } } diff --git a/control/kern/tproxy.c b/control/kern/tproxy.c index d1025b5..2474cbe 100644 --- a/control/kern/tproxy.c +++ b/control/kern/tproxy.c @@ -133,16 +133,6 @@ struct routing_result { __u8 dscp; }; -struct dst_routing_result { - __be32 ip[4]; - __be16 port; - __u16 recognize; - struct routing_result routing_result; -}; - -// force emitting struct into the ELF. -const struct dst_routing_result *_ __attribute__((unused)); - struct tuples_key { union ip6 sip; union ip6 dip; @@ -399,159 +389,6 @@ static __always_inline bool equal16(const __be32 x[4], const __be32 y[4]) { #endif } -static __always_inline __u32 l4_checksum_rel_off(__u8 proto) { - switch (proto) { - case IPPROTO_TCP: - return offsetof(struct tcphdr, check); - - case IPPROTO_UDP: - return offsetof(struct udphdr, check); - } - return 0; -} - -static __always_inline __u32 l4_checksum_off(__u32 link_h_len, __u8 proto, - __u8 ihl) { - return link_h_len + ihl * 4 + l4_checksum_rel_off(proto); -} - -static __always_inline int disable_l4_checksum(struct __sk_buff *skb, - __u32 link_h_len, __u8 l4proto, - __u8 ihl) { - __u32 l4_cksm_off = l4_checksum_off(link_h_len, l4proto, ihl); - // Set checksum zero. - __sum16 bak_cksm = 0; - return bpf_skb_store_bytes(skb, l4_cksm_off, &bak_cksm, sizeof(bak_cksm), 0); -} - -static __always_inline int rewrite_ip(struct __sk_buff *skb, __u32 link_h_len, - __u8 proto, __u8 ihl, __be32 old_ip[4], - __be32 new_ip[4], bool is_dest, - bool disable_l4_checksum) { - // Nothing to do. - if (equal16(old_ip, new_ip)) { - return 0; - } - // bpf_printk("%pI6->%pI6", old_ip, new_ip); - - __u32 l4_cksm_off = l4_checksum_off(link_h_len, proto, ihl); - int ret; - // BPF_F_PSEUDO_HDR indicates the part we want to modify is part of the - // pseudo header. - __u32 l4flags = BPF_F_PSEUDO_HDR; - if (proto == IPPROTO_UDP) { - l4flags |= BPF_F_MARK_MANGLED_0; - } - - if (skb->protocol == bpf_htons(ETH_P_IP)) { - - __be32 _old_ip = old_ip[3]; - __be32 _new_ip = new_ip[3]; - - int ret; - - if (!disable_l4_checksum) { - if ((ret = bpf_l4_csum_replace(skb, l4_cksm_off, _old_ip, _new_ip, - l4flags | sizeof(_new_ip)))) { - bpf_printk("bpf_l4_csum_replace: %d", ret); - return ret; - } - } - - if ((ret = bpf_l3_csum_replace(skb, IPV4_CSUM_OFF(link_h_len), _old_ip, - _new_ip, sizeof(_new_ip)))) { - return ret; - } - // bpf_printk("%pI4 -> %pI4", &_old_ip, &_new_ip); - - ret = bpf_skb_store_bytes( - skb, is_dest ? IPV4_DST_OFF(link_h_len) : IPV4_SRC_OFF(link_h_len), - &_new_ip, sizeof(_new_ip), 0); - if (ret) { - bpf_printk("bpf_skb_store_bytes: %d", ret); - return ret; - } - } else { - - if (!disable_l4_checksum) { - __s64 cksm = - bpf_csum_diff(old_ip, IPV6_BYTE_LENGTH, new_ip, IPV6_BYTE_LENGTH, 0); - if ((ret = bpf_l4_csum_replace(skb, l4_cksm_off, 0, cksm, l4flags))) { - bpf_printk("bpf_l4_csum_replace: %d", ret); - return ret; - } - } - - // bpf_printk("%pI6 -> %pI6", old_ip, new_ip); - - ret = bpf_skb_store_bytes( - skb, is_dest ? IPV6_DST_OFF(link_h_len) : IPV6_SRC_OFF(link_h_len), - new_ip, IPV6_BYTE_LENGTH, 0); - if (ret) { - bpf_printk("bpf_skb_store_bytes: %d", ret); - return ret; - } - } - - return 0; -} - -static __always_inline int rewrite_port(struct __sk_buff *skb, __u32 link_h_len, - __u8 proto, __u8 ihl, __be16 old_port, - __be16 new_port, bool is_dest, - bool disable_l4_checksum) { - // Nothing to do. - if (old_port == new_port) { - return 0; - } - - __u32 cksm_off = l4_checksum_off(link_h_len, proto, ihl), - port_off = link_h_len + ihl * 4; - if (!cksm_off) { - return -EINVAL; - } - __u32 l4flags = 0; - switch (proto) { - case IPPROTO_TCP: - if (is_dest) { - port_off += offsetof(struct tcphdr, dest); - } else { - port_off += offsetof(struct tcphdr, source); - } - break; - - case IPPROTO_UDP: - if (is_dest) { - port_off += offsetof(struct udphdr, dest); - } else { - port_off += offsetof(struct udphdr, source); - } - l4flags |= BPF_F_MARK_MANGLED_0; - break; - - default: - return -EINVAL; - } - - // bpf_printk("%u -> %u", bpf_ntohs(old_port), bpf_ntohs(new_port)); - - int ret; - - if (!disable_l4_checksum) { - if ((ret = bpf_l4_csum_replace(skb, cksm_off, old_port, new_port, - l4flags | sizeof(new_port)))) { - bpf_printk("bpf_l4_csum_replace: %d", ret); - return ret; - } - } - - if ((ret = bpf_skb_store_bytes(skb, port_off, &new_port, sizeof(new_port), - 0))) { - return ret; - } - return 0; -} - static __always_inline int handle_ipv6_extensions(const struct __sk_buff *skb, __u32 offset, __u32 hdr, struct icmp6hdr *icmp6h, struct tcphdr *tcph, @@ -715,176 +552,6 @@ parse_transport(const struct __sk_buff *skb, __u32 link_h_len, } } -static __always_inline int adjust_udp_len(struct __sk_buff *skb, - __u32 link_h_len, __u16 oldlen, - __u32 ihl, __u16 len_diff, - bool disable_l4_checksum) { - if (unlikely(!len_diff)) { - return 0; - } - - // Boundary check. - if (len_diff > 0) { - if (unlikely(bpf_ntohs(oldlen) + len_diff < len_diff)) { // overflow - bpf_printk("udp length overflow"); - return -EINVAL; - } - } else { - if (unlikely((__s32)bpf_ntohs(oldlen) + len_diff < 0)) { // not enough - bpf_printk("udp length not enough"); - return -EINVAL; - } - } - __be16 newlen = bpf_htons(bpf_ntohs(oldlen) + len_diff); - - // Calculate checksum and store the new value. - int ret; - __u32 udp_csum_off = l4_checksum_off(link_h_len, IPPROTO_UDP, ihl); - - if (!disable_l4_checksum) { // replace twice because len exists both pseudo - // hdr and hdr. - if ((ret = bpf_l4_csum_replace( - skb, udp_csum_off, oldlen, newlen, - sizeof(oldlen) | BPF_F_PSEUDO_HDR | // udp len is in the pseudo hdr - BPF_F_MARK_MANGLED_0))) { - bpf_printk("bpf_l4_csum_replace newudplen: %d", ret); - return ret; - } - if ((ret = bpf_l4_csum_replace(skb, udp_csum_off, oldlen, newlen, - sizeof(oldlen) | BPF_F_MARK_MANGLED_0))) { - bpf_printk("bpf_l4_csum_replace newudplen: %d", ret); - return ret; - } - } - - if ((ret = bpf_skb_store_bytes( - skb, link_h_len + ihl * 4 + offsetof(struct udphdr, len), &newlen, - sizeof(oldlen), 0))) { - bpf_printk("bpf_skb_store_bytes newudplen: %d", ret); - return ret; - } - return 0; -} - -static __always_inline int adjust_ipv4_len(struct __sk_buff *skb, - __u32 link_h_len, __u16 oldlen, - __u16 len_diff) { - if (unlikely(!len_diff)) { - return 0; - } - - // Boundary check. - if (len_diff > 0) { - if (unlikely(bpf_ntohs(oldlen) + len_diff < len_diff)) { // overflow - bpf_printk("ip length overflow"); - return -EINVAL; - } - } else { - if (unlikely((__s32)bpf_ntohs(oldlen) + len_diff < 0)) { // not enough - bpf_printk("ip length not enough"); - return -EINVAL; - } - } - __be16 newlen = bpf_htons(bpf_ntohs(oldlen) + len_diff); - - // Calculate checksum and store the new value. - int ret; - if ((ret = bpf_l3_csum_replace(skb, IPV4_CSUM_OFF(link_h_len), oldlen, newlen, - sizeof(oldlen)))) { - bpf_printk("bpf_l3_csum_replace newudplen: %d", ret); - return ret; - } - if ((ret = bpf_skb_store_bytes(skb, - link_h_len + offsetof(struct iphdr, tot_len), - &newlen, sizeof(oldlen), 0))) { - bpf_printk("bpf_skb_store_bytes newiplen: %d", ret); - return ret; - } - return 0; -} - -static __always_inline int -decap_after_udp_hdr(struct __sk_buff *skb, __u32 link_h_len, __u8 ihl, - __be16 ipv4hdr_tot_len, void *to, __u32 decap_hdrlen, - bool (*prevent_pop)(void *to), bool disable_l4_checksum) { - if (unlikely(decap_hdrlen % 4 != 0)) { - bpf_printk("encap_after_udp_hdr: unexpected decap_hdrlen value %u :must " - "be a multiple of 4", - decap_hdrlen); - return -EINVAL; - } - int ret = 0; - long ip_off = link_h_len; - // Calculate offsets using add instead of subtract to avoid verifier problems. - long ipp_len = ihl * 4; - - // Must check lower boundary for packet offset (and set the type of the - // variables to signed long). - if (skb->data + ip_off + ipp_len > skb->data_end) { - return -EINVAL; - } - - // Backup for further use. - struct udphdr reserved_udphdr; - if ((ret = bpf_skb_load_bytes(skb, ip_off + ipp_len, &reserved_udphdr, - sizeof(struct udphdr)))) { - bpf_printk("bpf_skb_load_bytes: %d", ret); - return ret; - } - - // Load the hdr to decap. - if ((ret = bpf_skb_load_bytes(skb, ip_off + ipp_len + sizeof(struct udphdr), - to, decap_hdrlen))) { - bpf_printk("bpf_skb_load_bytes decap_hdr: %d", ret); - return ret; - } - - // Move the udphdr to the front of the real UDP payload. - if ((ret = - bpf_skb_store_bytes(skb, ip_off + ipp_len + decap_hdrlen, - &reserved_udphdr, sizeof(reserved_udphdr), 0))) { - bpf_printk("bpf_skb_store_bytes reserved_udphdr: %d", ret); - return ret; - } - - if (prevent_pop == NULL || !prevent_pop(to)) { - // Adjust room to decap the header. - if ((ret = bpf_skb_adjust_room(skb, -decap_hdrlen, BPF_ADJ_ROOM_NET, - BPF_F_ADJ_ROOM_NO_CSUM_RESET))) { - bpf_printk("UDP ADJUST ROOM(decap): %d", ret); - return ret; - } - - // Rewrite ip len. - if (skb->protocol == bpf_htons(ETH_P_IP)) { - if ((ret = adjust_ipv4_len(skb, link_h_len, ipv4hdr_tot_len, - -decap_hdrlen))) { - bpf_printk("adjust_ip_len: %d", ret); - return ret; - } - } - - // Rewrite udp len. - if ((ret = adjust_udp_len(skb, link_h_len, reserved_udphdr.len, ihl, - -decap_hdrlen, disable_l4_checksum))) { - bpf_printk("adjust_udp_len: %d", ret); - return ret; - } - - if (!disable_l4_checksum) { - // Rewrite udp checksum. - __u32 udp_csum_off = l4_checksum_off(link_h_len, IPPROTO_UDP, ihl); - __s64 cksm = bpf_csum_diff(to, decap_hdrlen, 0, 0, 0); - if ((ret = bpf_l4_csum_replace(skb, udp_csum_off, 0, cksm, - BPF_F_MARK_MANGLED_0))) { - bpf_printk("bpf_l4_csum_replace 2: %d", ret); - return ret; - } - } - } - return 0; -} - // Do not use __always_inline here because this function is too heavy. // low -> high: outbound(8b) mark(32b) unused(23b) sign(1b) static __s64 __attribute__((noinline)) @@ -1134,11 +801,6 @@ route(const __u32 flag[8], const void *l4hdr, const __be32 saddr[4], #undef _dscp } -static bool __always_inline is_not_to_lan(void *_ori_src) { - struct dst_routing_result *ori_src = _ori_src; - return ori_src->routing_result.outbound == IS_WAN; -} - static __always_inline __u32 get_link_h_len(__u32 ifindex, volatile __u32 *link_h_len) { __u32 *plink_h_len = bpf_map_lookup_elem(&linklen_map, &ifindex); @@ -1188,78 +850,6 @@ assign_socket(struct __sk_buff *skb, struct bpf_sock_tuple *tuple, return assign_socket_udp(skb, tuple, len); } -// SNAT for UDP packet. -SEC("tc/egress") -int tproxy_lan_egress(struct __sk_buff *skb) { - if (skb->ingress_ifindex != NOWHERE_IFINDEX) { - return TC_ACT_PIPE; - } - struct ethhdr ethh; - struct iphdr iph; - struct ipv6hdr ipv6h; - struct icmp6hdr icmp6h; - struct tcphdr tcph; - struct udphdr udph; - __u8 ihl; - __u8 l4proto; - __u32 link_h_len; - if (get_link_h_len(skb->ifindex, &link_h_len)) { - return TC_ACT_OK; - } - int ret = parse_transport(skb, link_h_len, ðh, &iph, &ipv6h, &icmp6h, - &tcph, &udph, &ihl, &l4proto); - if (ret) { - bpf_printk("parse_transport: %d", ret); - return TC_ACT_OK; - } - switch (l4proto) { - case IPPROTO_ICMPV6: - if (icmp6h.icmp6_type == 137) { - // REDIRECT (NDP) - return TC_ACT_SHOT; - } - return TC_ACT_PIPE; - case IPPROTO_UDP: - break; - default: - return TC_ACT_PIPE; - } - - __be16 tproxy_port = PARAM.tproxy_port; - if (!tproxy_port) { - return TC_ACT_PIPE; - } - struct tuples tuples; - get_tuples(skb, &tuples, &iph, &ipv6h, &tcph, &udph, l4proto); - if (tproxy_port != tuples.five.sport) { - return TC_ACT_PIPE; - } - - struct dst_routing_result ori_src; - if ((ret = decap_after_udp_hdr( - skb, link_h_len, ihl, - skb->protocol == bpf_htons(ETH_P_IP) ? iph.tot_len : 0, &ori_src, - sizeof(ori_src), is_not_to_lan, true))) { - return TC_ACT_SHOT; - } - if (is_not_to_lan(&ori_src)) { - return TC_ACT_PIPE; - } - if ((ret = rewrite_ip(skb, link_h_len, l4proto, ihl, - tuples.five.sip.u6_addr32, ori_src.ip, false, true))) { - return TC_ACT_SHOT; - } - if ((ret = rewrite_port(skb, link_h_len, l4proto, ihl, tuples.five.sport, - ori_src.port, false, true))) { - return TC_ACT_SHOT; - } - disable_l4_checksum(skb, link_h_len, l4proto, ihl); - // bpf_printk("from %pI6 to %pI6", tuples.five.sip, ori_src.ip); - // bpf_printk("from %u to %u", bpf_ntohs(tuples.five.sport), - // bpf_ntohs(ori_src.port)); - return TC_ACT_OK; -} - SEC("tc/ingress") int tproxy_lan_ingress(struct __sk_buff *skb) { struct ethhdr ethh; diff --git a/control/tcp.go b/control/tcp.go index c429db6..55a6345 100644 --- a/control/tcp.go +++ b/control/tcp.go @@ -162,7 +162,7 @@ func (c *ControlPlane) RouteDialTcp(p *RouteDialParam) (conn netproxy.Conn, err "dscp": routingResult.Dscp, "pname": ProcessName2String(routingResult.Pname[:]), "mac": Mac2String(routingResult.Mac[:]), - }).Infof("%v <-> %v", RefineSourceToShow(src, dst.Addr(), consts.LanWanFlag_NotApplicable), dialTarget) + }).Infof("%v <-> %v", RefineSourceToShow(src, dst.Addr()), dialTarget) } ctx, cancel := context.WithTimeout(context.TODO(), consts.DefaultDialTimeout) defer cancel() diff --git a/control/udp.go b/control/udp.go index 416c8e6..a647580 100644 --- a/control/udp.go +++ b/control/udp.go @@ -6,7 +6,6 @@ package control import ( - "encoding/binary" "errors" "fmt" "net" @@ -19,7 +18,6 @@ import ( ob "github.com/daeuniverse/dae/component/outbound" "github.com/daeuniverse/dae/component/outbound/dialer" "github.com/daeuniverse/dae/component/sniffing" - internal "github.com/daeuniverse/dae/pkg/ebpf_internal" "github.com/daeuniverse/softwind/pool" dnsmessage "github.com/miekg/dns" "github.com/sirupsen/logrus" @@ -50,44 +48,8 @@ func ChooseNatTimeout(data []byte, sniffDns bool) (dmsg *dnsmessage.Msg, timeout return nil, DefaultNatTimeout } -func sendPktWithHdrWithFlag(data []byte, realFrom netip.AddrPort, lConn *net.UDPConn, to netip.AddrPort, lanWanFlag consts.LanWanFlag) error { - realFrom16 := realFrom.Addr().As16() - hdr := bpfDstRoutingResult{ - Ip: common.Ipv6ByteSliceToUint32Array(realFrom16[:]), - Port: common.Htons(realFrom.Port()), - RoutingResult: bpfRoutingResult{ - Outbound: uint8(lanWanFlag), // Pass some message to the kernel program. - }, - } - // Do not put this 'buf' because it has been taken by buffer. - b := pool.GetBuffer() - defer pool.PutBuffer(b) - // Use internal.NativeEndian due to already big endian. - if err := binary.Write(b, internal.NativeEndian, hdr); err != nil { - return err - } - b.Write(data) - //logrus.Debugln("sendPktWithHdrWithFlag: from", realFrom, "to", to) - if ipversion := consts.IpVersionFromAddr(to.Addr()); consts.IpVersionFromAddr(lConn.LocalAddr().(*net.UDPAddr).AddrPort().Addr()) != ipversion { - // ip versions unmatched. - if ipversion == consts.IpVersionStr_4 { - // 4 to 6 - to = netip.AddrPortFrom(netip.AddrFrom16(to.Addr().As16()), to.Port()) - } else { - // Shouldn't happen. - return fmt.Errorf("unmatched ipversions") - } - } - _, err := lConn.WriteToUDPAddrPort(b.Bytes(), to) - return err -} - // sendPkt uses bind first, and fallback to send hdr if addr is in use. -func sendPkt(data []byte, from netip.AddrPort, realTo, to netip.AddrPort, lConn *net.UDPConn, lanWanFlag consts.LanWanFlag) (err error) { - - if lanWanFlag == consts.LanWanFlag_IsWan { - return sendPktWithHdrWithFlag(data, from, lConn, to, lanWanFlag) - } +func sendPkt(data []byte, from netip.AddrPort, realTo, to netip.AddrPort, lConn *net.UDPConn) (err error) { transparentTimeout := AnyfromTimeout if from.Port() == 53 { @@ -113,18 +75,9 @@ func sendPkt(data []byte, from netip.AddrPort, realTo, to netip.AddrPort, lConn } func (c *ControlPlane) handlePkt(lConn *net.UDPConn, data []byte, src, pktDst, realDst netip.AddrPort, routingResult *bpfRoutingResult, skipSniffing bool) (err error) { - var lanWanFlag consts.LanWanFlag var realSrc netip.AddrPort var domain string - useAssign := pktDst == realDst // Use sk_assign instead of modify target ip/port. - if useAssign { - lanWanFlag = consts.LanWanFlag_IsLan - realSrc = src - } else { - lanWanFlag = consts.LanWanFlag_IsWan - // From localhost, so dst IP is src IP. - realSrc = netip.AddrPortFrom(pktDst.Addr(), src.Port()) - } + realSrc = src // To keep consistency with kernel program, we only sniff DNS request sent to 53. dnsMessage, natTimeout := ChooseNatTimeout(data, realDst.Port() == 53) @@ -185,7 +138,6 @@ func (c *ControlPlane) handlePkt(lConn *net.UDPConn, data []byte, src, pktDst, r } if isDns { return c.dnsController.Handle_(dnsMessage, &udpRequest{ - lanWanFlag: lanWanFlag, realSrc: realSrc, realDst: realDst, src: src, @@ -224,7 +176,7 @@ func (c *ControlPlane) handlePkt(lConn *net.UDPConn, data []byte, src, pktDst, r getNew: if retry > MaxRetry { c.log.WithFields(logrus.Fields{ - "src": RefineSourceToShow(realSrc, realDst.Addr(), lanWanFlag), + "src": RefineSourceToShow(realSrc, realDst.Addr()), "network": networkType.String(), "dialer": ue.Dialer.Property().Name, "retry": retry, @@ -235,7 +187,7 @@ getNew: // Handler handles response packets and send it to the client. Handler: func(data []byte, from netip.AddrPort) (err error) { // Do not return conn-unrelated err in this func. - return sendPkt(data, from, realSrc, src, lConn, lanWanFlag) + return sendPkt(data, from, realSrc, src, lConn) }, NatTimeout: natTimeout, GetDialOption: func() (option *DialOption, err error) { @@ -299,7 +251,7 @@ getNew: if c.log.IsLevelEnabled(logrus.DebugLevel) { c.log.WithFields(logrus.Fields{ - "src": RefineSourceToShow(realSrc, realDst.Addr(), lanWanFlag), + "src": RefineSourceToShow(realSrc, realDst.Addr()), "network": networkType.String(), "dialer": ue.Dialer.Property().Name, "retry": retry, @@ -346,7 +298,7 @@ getNew: "pname": ProcessName2String(routingResult.Pname[:]), "mac": Mac2String(routingResult.Mac[:]), } - c.log.WithFields(fields).Infof("%v <-> %v", RefineSourceToShow(realSrc, realDst.Addr(), lanWanFlag), dialTarget) + c.log.WithFields(fields).Infof("%v <-> %v", RefineSourceToShow(realSrc, realDst.Addr()), dialTarget) } return nil