func copyUDPPacket(raw []byte, ip *packet.IPv4, udp *packet.UDP) *udpPacket { iphdr := packet.NewIPv4() udphdr := packet.NewUDP() pkt := newUDPPacket() if len(udp.Payload) == 0 { // shallow copy headers // for now, we don't need deep copy if no payload *iphdr = *ip *udphdr = *udp pkt.ip = iphdr pkt.udp = udphdr } else { // get a block of buffer, make a deep copy buf := newBuffer() n := copy(buf, raw) pkt.mtuBuf = buf pkt.wire = buf[:n] packet.ParseIPv4(pkt.wire, iphdr) packet.ParseUDP(iphdr.Payload, udphdr) pkt.ip = iphdr pkt.udp = udphdr } return pkt }
func copyTCPPacket(raw []byte, ip *packet.IPv4, tcp *packet.TCP) *tcpPacket { iphdr := packet.NewIPv4() tcphdr := packet.NewTCP() pkt := newTCPPacket() if len(tcp.Payload) == 0 { // shallow copy headers // for now, we don't need deep copy if no payload *iphdr = *ip *tcphdr = *tcp pkt.ip = iphdr pkt.tcp = tcphdr } else { // get a block of buffer, make a deep copy buf := newBuffer() n := copy(buf, raw) pkt.mtuBuf = buf pkt.wire = buf[:n] packet.ParseIPv4(pkt.wire, iphdr) packet.ParseTCP(iphdr.Payload, tcphdr) pkt.ip = iphdr pkt.tcp = tcphdr } return pkt }
func (t2s *Tun2Socks) Run() { syscall.SetNonblock(int(t2s.dev.Fd()), false) // writer go func() { for { select { case pkt := <-t2s.writeCh: switch pkt.(type) { case *tcpPacket: tcp := pkt.(*tcpPacket) t2s.dev.Write(tcp.wire) releaseTCPPacket(tcp) case *udpPacket: udp := pkt.(*udpPacket) t2s.dev.Write(udp.wire) releaseUDPPacket(udp) } case <-t2s.writerStopCh: log.Printf("quit tun2socks writer") return } } }() // reader var buf [MTU]byte var ip packet.IPv4 var tcp packet.TCP var udp packet.UDP for { select { case <-t2s.readerStopCh: log.Printf("quit tun2socks reader") return default: n, e := t2s.dev.Read(buf[:]) if e != nil { // TODO: stop at critical error log.Printf("read packet error: %s", e) return } e = packet.ParseIPv4(buf[:n], &ip) if e != nil { log.Printf("error to parse IPv4: %s", e) continue } if t2s.publicOnly { if !ip.DstIP.IsGlobalUnicast() { continue } if isPrivate(ip.DstIP) { continue } } switch ip.Protocol { case packet.IPProtocolTCP: e = packet.ParseTCP(ip.Payload, &tcp) if e != nil { log.Printf("error to parse TCP: %s", e) continue } t2s.tcp(buf[:n], &ip, &tcp) case packet.IPProtocolUDP: e = packet.ParseUDP(ip.Payload, &udp) if e != nil { log.Printf("error to parse UDP: %s", e) continue } t2s.udp(buf[:n], &ip, &udp) default: // Unsupported packets log.Printf("Unsupported packet: protocol %d", ip.Protocol) } } } }