func (c *UDPConn) writeUDPClient(dgram *gosocks5.UDPDatagram) error { if c.udp != nil { dgram.Header.Rsv = 0 buffer := bytes.Buffer{} dgram.Write(&buffer) _, err := c.udp.WriteTo(buffer.Bytes(), c.addr) return err } dgram.Header.Rsv = uint16(len(dgram.Data)) return dgram.Write(c.tcp) }
func (c *UDPConn) writeUDPServer(dgram *gosocks5.UDPDatagram) error { if c.udp != nil { addr, err := net.ResolveUDPAddr("udp", dgram.Header.Addr.String()) if err != nil { glog.V(LWARNING).Infoln(err) return nil // drop silently } _, err = c.udp.WriteTo(dgram.Data, addr) return err } dgram.Header.Rsv = uint16(len(dgram.Data)) return dgram.Write(c.tcp) }
func (s *Socks5Server) tunnelUDP(uc *net.UDPConn, cc net.Conn, client bool) (err error) { errc := make(chan error, 2) var clientAddr *net.UDPAddr go func() { b := make([]byte, LargeBufferSize) for { n, addr, err := uc.ReadFromUDP(b) if err != nil { errc <- err return } var dgram *gosocks5.UDPDatagram if client { // pipe from relay to tunnel dgram, err = gosocks5.ReadUDPDatagram(bytes.NewReader(b[:n])) if err != nil { errc <- err return } if clientAddr == nil { clientAddr = addr } dgram.Header.Rsv = uint16(len(dgram.Data)) if err := dgram.Write(cc); err != nil { errc <- err return } glog.V(LDEBUG).Infof("[udp-tun] %s >>> %s length: %d", uc.LocalAddr(), dgram.Header.Addr, len(dgram.Data)) } else { // pipe from peer to tunnel dgram = gosocks5.NewUDPDatagram( gosocks5.NewUDPHeader(uint16(n), 0, ToSocksAddr(addr)), b[:n]) if err := dgram.Write(cc); err != nil { errc <- err return } glog.V(LDEBUG).Infof("[udp-tun] %s <<< %s length: %d", cc.RemoteAddr(), dgram.Header.Addr, len(dgram.Data)) } } }() go func() { for { dgram, err := gosocks5.ReadUDPDatagram(cc) if err != nil { errc <- err return } if client { // pipe from tunnel to relay if clientAddr == nil { continue } dgram.Header.Rsv = 0 buf := bytes.Buffer{} dgram.Write(&buf) if _, err := uc.WriteToUDP(buf.Bytes(), clientAddr); err != nil { errc <- err return } glog.V(LDEBUG).Infof("[udp-tun] %s <<< %s length: %d", uc.LocalAddr(), dgram.Header.Addr, len(dgram.Data)) } else { // pipe from tunnel to peer addr, err := net.ResolveUDPAddr("udp", dgram.Header.Addr.String()) if err != nil { continue // drop silently } if _, err := uc.WriteToUDP(dgram.Data, addr); err != nil { errc <- err return } glog.V(LDEBUG).Infof("[udp-tun] %s >>> %s length: %d", cc.RemoteAddr(), addr, len(dgram.Data)) } } }() select { case err = <-errc: } return }