예제 #1
0
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
}
예제 #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)
			}
		}
	}
}