diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 70617a9..8daf24f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -111,10 +111,10 @@ jobs: popd || exit 1 FILE=./dae-$ASSET_NAME.zip DGST=$FILE.dgst - md5sum $FILE | awk '{print $1}' >>$DGST - shasum -a 1 $FILE | awk '{print $1}' >>$DGST - shasum -a 256 $FILE | awk '{print $1}' >>$DGST - shasum -a 512 $FILE | awk '{print $1}' >>$DGST + md5sum $FILE >>$DGST + shasum -a 1 $FILE >>$DGST + shasum -a 256 $FILE >>$DGST + shasum -a 512 $FILE >>$DGST - name: Upload files to Artifacts uses: actions/upload-artifact@v3 diff --git a/component/control/kern/tproxy.c b/component/control/kern/tproxy.c index 34ce538..2ef55cb 100644 --- a/component/control/kern/tproxy.c +++ b/component/control/kern/tproxy.c @@ -966,7 +966,6 @@ routing(const __u32 flag[6], const void *l4hdr, const __be32 saddr[4], } lpm_key_instance.trie_key.prefixlen = IPV6_BYTE_LENGTH * 8; __builtin_memcpy(lpm_key_instance.data, daddr, IPV6_BYTE_LENGTH); - bpf_printk("daddr: %pI6", daddr); key = MatchType_IpSet; if (unlikely((ret = bpf_map_update_elem(&lpm_key_map, &key, &lpm_key_instance, BPF_ANY)))) { @@ -1189,52 +1188,63 @@ int tproxy_lan_ingress(struct __sk_buff *skb) { ip -6 rule del fwmark 0x80000000/0x80000000 table 1000 ip -6 route del local ::/0 dev lo table 1000 */ - - // Socket lookup and assign skb to existing socket connection. struct bpf_sock_tuple tuple = {0}; __u32 tuple_size; - if (ipversion == 4) { - tuple.ipv4.daddr = tuples.dst.ip[3]; - tuple.ipv4.saddr = tuples.src.ip[3]; - tuple.ipv4.dport = tuples.dst.port; - tuple.ipv4.sport = tuples.src.port; - tuple_size = sizeof(tuple.ipv4); - } else { - __builtin_memcpy(tuple.ipv6.daddr, tuples.dst.ip, IPV6_BYTE_LENGTH); - __builtin_memcpy(tuple.ipv6.saddr, tuples.src.ip, IPV6_BYTE_LENGTH); - tuple.ipv6.dport = tuples.dst.port; - tuple.ipv6.sport = tuples.src.port; - tuple_size = sizeof(tuple.ipv6); - } - struct bpf_sock *sk; - bool is_old_conn = false; + bool is_old_conn; + __u32 flag[6] = {0}; + void *l4hdr; - if (l4proto == IPPROTO_TCP) { - // TCP. + // Socket lookup and assign skb to existing socket connection. + if ((bpf_map_lookup_elem(&routing_tuples_map, &tuples))) { + // Should be old connection. + is_old_conn = true; - sk = bpf_skc_lookup_tcp(skb, &tuple, tuple_size, BPF_F_CURRENT_NETNS, 0); - if (sk) { - if (sk->state != BPF_TCP_LISTEN) { - // Old connection. - is_old_conn = true; + if (ipversion == 4) { + tuple.ipv4.daddr = tuples.dst.ip[3]; + tuple.ipv4.saddr = tuples.src.ip[3]; + tuple.ipv4.dport = tuples.dst.port; + tuple.ipv4.sport = tuples.src.port; + tuple_size = sizeof(tuple.ipv4); + } else { + __builtin_memcpy(tuple.ipv6.daddr, tuples.dst.ip, IPV6_BYTE_LENGTH); + __builtin_memcpy(tuple.ipv6.saddr, tuples.src.ip, IPV6_BYTE_LENGTH); + tuple.ipv6.dport = tuples.dst.port; + tuple.ipv6.sport = tuples.src.port; + tuple_size = sizeof(tuple.ipv6); + } + + if (l4proto == IPPROTO_TCP) { + // TCP. + if (tcph.syn && !tcph.ack) { + goto new_connection; + } + + sk = bpf_skc_lookup_tcp(skb, &tuple, tuple_size, BPF_F_CURRENT_NETNS, 0); + if (sk) { + if (sk->state != BPF_TCP_LISTEN) { + goto assign; + } + bpf_sk_release(sk); + } + } else { + // UDP. + + sk = bpf_sk_lookup_udp(skb, &tuple, tuple_size, BPF_F_CURRENT_NETNS, 0); + if (sk) { goto assign; } - bpf_sk_release(sk); - } - } else { - // UDP. - - sk = bpf_sk_lookup_udp(skb, &tuple, tuple_size, BPF_F_CURRENT_NETNS, 0); - if (sk) { - goto assign; } } - // Routing for new connection. - __u32 flag[6] = {0}; // TCP - void *l4hdr; +// Routing for new connection. +new_connection: if (l4proto == IPPROTO_TCP) { + if (!(tcph.syn && !tcph.ack)) { + // Not a new TCP connection. + // Perhaps single-arm. + return TC_ACT_OK; + } l4hdr = &tcph; flag[0] = L4ProtoType_TCP; } else { diff --git a/component/control/tcp.go b/component/control/tcp.go index 553d5bf..5dc9a88 100644 --- a/component/control/tcp.go +++ b/component/control/tcp.go @@ -20,7 +20,7 @@ func (c *ControlPlane) handleConn(lConn net.Conn) (err error) { defer lConn.Close() src := lConn.RemoteAddr().(*net.TCPAddr).AddrPort() dst := lConn.LocalAddr().(*net.TCPAddr).AddrPort() - outboundIndex, err := c.RetrieveOutboundIndex(src, dst, unix.IPPROTO_TCP) + outboundIndex, _, err := c.RetrieveOutboundIndex(src, dst, unix.IPPROTO_TCP) if err != nil { return fmt.Errorf("RetrieveOutboundIndex: %w", err) } diff --git a/component/control/tproxy_utils.go b/component/control/tproxy_utils.go index af68f59..ba72651 100644 --- a/component/control/tproxy_utils.go +++ b/component/control/tproxy_utils.go @@ -16,12 +16,11 @@ import ( "syscall" ) -func (c *ControlPlaneCore) RetrieveOutboundIndex(src, dst netip.AddrPort, l4proto uint8) (consts.OutboundIndex, error) { +func (c *ControlPlaneCore) RetrieveOutboundIndex(src, dst netip.AddrPort, l4proto uint8) (outboundIndex consts.OutboundIndex, tuples *bpfTuples, err error) { srcIp6 := src.Addr().As16() dstIp6 := dst.Addr().As16() - var outboundIndex uint32 - if err := c.bpf.RoutingTuplesMap.Lookup(bpfTuples{ + tuples = &bpfTuples{ Src: bpfIpPort{ Ip: common.Ipv6ByteSliceToUint32Array(srcIp6[:]), Port: internal.Htons(src.Port()), @@ -31,13 +30,16 @@ func (c *ControlPlaneCore) RetrieveOutboundIndex(src, dst netip.AddrPort, l4prot Port: internal.Htons(dst.Port()), }, L4proto: l4proto, - }, &outboundIndex); err != nil { - return 0, fmt.Errorf("reading map: key %v: %w", src.String(), err) } - if outboundIndex > uint32(consts.OutboundLogicalMax) { - return 0, fmt.Errorf("bad outbound index") + + var _outboundIndex uint32 + if err := c.bpf.RoutingTuplesMap.Lookup(tuples, &_outboundIndex); err != nil { + return 0, nil, fmt.Errorf("reading map: key %v: %w", src.String(), err) } - return consts.OutboundIndex(outboundIndex), nil + if _outboundIndex > uint32(consts.OutboundLogicalMax) { + return 0, nil, fmt.Errorf("bad outbound index") + } + return consts.OutboundIndex(_outboundIndex), tuples, nil } func RetrieveOriginalDest(oob []byte) netip.AddrPort { diff --git a/component/control/udp.go b/component/control/udp.go index db34f23..c9abff5 100644 --- a/component/control/udp.go +++ b/component/control/udp.go @@ -124,7 +124,7 @@ func (c *ControlPlane) RelayToUDP(to netip.AddrPort, isDNS bool, dummyFrom *neti } func (c *ControlPlane) handlePkt(data []byte, src, dst netip.AddrPort) (err error) { - outboundIndex, err := c.RetrieveOutboundIndex(src, dst, unix.IPPROTO_UDP) + outboundIndex, _, err := c.RetrieveOutboundIndex(src, dst, unix.IPPROTO_UDP) if err != nil { return fmt.Errorf("RetrieveOutboundIndex: %w", err) } diff --git a/insert.sh b/insert.sh index d22d24a..b2d4fda 100755 --- a/insert.sh +++ b/insert.sh @@ -13,8 +13,8 @@ sudo rm -rf /sys/fs/bpf/tc/globals/* clang -O2 -g -Wall -Werror -c component/control/kern/tproxy.c -target bpf -D__TARGET_ARCH_x86 -o foo.o sudo tc filter del dev $lan ingress sudo tc filter del dev $lan egress -sudo tc filter del dev $wan ingress -sudo tc filter del dev $wan egress +# sudo tc filter del dev $wan ingress +# sudo tc filter del dev $wan egress sudo tc filter add dev $lan ingress bpf direct-action obj foo.o sec tc/ingress # sudo tc filter add dev $lan egress bpf direct-action obj foo.o sec tc/egress # sudo tc filter add dev $wan ingress bpf direct-action obj foo.o sec tc/wan_ingress