Пример #1
0
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
}
Пример #2
0
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)
			}
		}
	}
}