func (s *Socks5Server) udpConnect(addr string) { raddr, err := net.ResolveUDPAddr("udp", addr) if err != nil { glog.V(LINFO).Infof("[udp] %s -> %s : %s", s.conn.RemoteAddr(), addr, err) gosocks5.NewReply(gosocks5.Failure, nil).Write(s.conn) return } if err := gosocks5.NewReply(gosocks5.Succeeded, nil).Write(s.conn); err != nil { glog.V(LINFO).Infof("[udp] %s <- %s : %s", s.conn.RemoteAddr(), addr, err) return } glog.V(LINFO).Infof("[udp] %s <-> %s", s.conn.RemoteAddr(), raddr) defer glog.V(LINFO).Infof("[udp] %s >-< %s", s.conn.RemoteAddr(), raddr) for { dgram, err := gosocks5.ReadUDPDatagram(s.conn) if err != nil { glog.V(LWARNING).Infof("[udp] %s -> %s : %s", s.conn.RemoteAddr(), addr, err) return } go func() { b := make([]byte, LargeBufferSize) relay, err := net.DialUDP("udp", nil, raddr) if err != nil { glog.V(LWARNING).Infof("[udp] %s -> %s : %s", s.conn.RemoteAddr(), raddr, err) return } defer relay.Close() if _, err := relay.Write(dgram.Data); err != nil { glog.V(LWARNING).Infof("[udp] %s -> %s : %s", s.conn.RemoteAddr(), raddr, err) return } glog.V(LDEBUG).Infof("[udp-tun] %s >>> %s length: %d", s.conn.RemoteAddr(), raddr, len(dgram.Data)) relay.SetReadDeadline(time.Now().Add(time.Second * 60)) n, err := relay.Read(b) if err != nil { glog.V(LWARNING).Infof("[udp] %s <- %s : %s", s.conn.RemoteAddr(), raddr, err) return } relay.SetReadDeadline(time.Time{}) glog.V(LDEBUG).Infof("[udp-tun] %s <<< %s length: %d", s.conn.RemoteAddr(), raddr, n) s.conn.SetWriteDeadline(time.Now().Add(time.Second * 90)) if err := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(uint16(n), 0, dgram.Header.Addr), b[:n]).Write(s.conn); err != nil { glog.V(LWARNING).Infof("[udp] %s <- %s : %s", s.conn.RemoteAddr(), raddr, err) return } s.conn.SetWriteDeadline(time.Time{}) }() } }
func (c *UDPConn) readUDPServer() (*gosocks5.UDPDatagram, error) { if c.udp != nil { b := make([]byte, 65535) n, addr, err := c.udp.ReadFrom(b) if err != nil { return nil, err } dgram := gosocks5.NewUDPDatagram( gosocks5.NewUDPHeader(0, 0, ToSocksAddr(addr)), b[:n]) return dgram, nil } return gosocks5.ReadUDPDatagram(c.tcp) }
func srvTunnelUDP(conn net.Conn, uconn *net.UDPConn) { go func() { b := make([]byte, 16*1024) for { n, addr, err := uconn.ReadFromUDP(b) if err != nil { if glog.V(LWARNING) { glog.Warningln(err) } return } udp := gosocks5.NewUDPDatagram( gosocks5.NewUDPHeader(uint16(n), 0, ToSocksAddr(addr)), b[:n]) //log.Println("r", udp.Header) if err := udp.Write(conn); err != nil { if glog.V(LWARNING) { glog.Warningln(err) } return } } }() for { udp, err := gosocks5.ReadUDPDatagram(conn) if err != nil { if glog.V(LWARNING) { glog.Warningln(err) } return } //log.Println("w", udp.Header) addr, err := net.ResolveUDPAddr("udp", udp.Header.Addr.String()) if err != nil { if glog.V(LWARNING) { glog.Warningln(err) } continue // drop silently } if _, err := uconn.WriteToUDP(udp.Data, addr); err != nil { if glog.V(LWARNING) { glog.Warningln(err) } return } } }
func srvTunnelUDP(conn net.Conn, uconn *net.UDPConn) { go func() { b := lpool.Take() defer lpool.put(b) for { n, addr, err := uconn.ReadFromUDP(b) if err != nil { log.Println(err) return } udp := gosocks5.NewUDPDatagram( gosocks5.NewUDPHeader(uint16(n), 0, ToSocksAddr(addr)), b[:n]) //log.Println("r", udp.Header) if err := udp.Write(conn); err != nil { log.Println(err) return } } }() for { udp, err := gosocks5.ReadUDPDatagram(conn) if err != nil { log.Println(err) return } //log.Println("w", udp.Header) addr, err := net.ResolveUDPAddr("udp", udp.Header.Addr.String()) if err != nil { log.Println(err) continue // drop silently } if _, err := uconn.WriteToUDP(udp.Data, addr); err != nil { log.Println(err) return } } }
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 }
func (s *Socks5Server) transportUDP(relay, peer *net.UDPConn) (err error) { errc := make(chan error, 2) var clientAddr *net.UDPAddr go func() { b := make([]byte, LargeBufferSize) for { n, laddr, err := relay.ReadFromUDP(b) if err != nil { errc <- err return } if clientAddr == nil { clientAddr = laddr } dgram, err := gosocks5.ReadUDPDatagram(bytes.NewReader(b[:n])) if err != nil { errc <- err return } raddr, err := net.ResolveUDPAddr("udp", dgram.Header.Addr.String()) if err != nil { continue // drop silently } if _, err := peer.WriteToUDP(dgram.Data, raddr); err != nil { errc <- err return } glog.V(LDEBUG).Infof("[socks5-udp] %s >>> %s length: %d", relay.LocalAddr(), raddr, len(dgram.Data)) } }() go func() { b := make([]byte, LargeBufferSize) for { n, raddr, err := peer.ReadFromUDP(b) if err != nil { errc <- err return } if clientAddr == nil { continue } buf := bytes.Buffer{} dgram := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(0, 0, ToSocksAddr(raddr)), b[:n]) dgram.Write(&buf) if _, err := relay.WriteToUDP(buf.Bytes(), clientAddr); err != nil { errc <- err return } glog.V(LDEBUG).Infof("[socks5-udp] %s <<< %s length: %d", relay.LocalAddr(), raddr, len(dgram.Data)) } }() select { case err = <-errc: //log.Println("w exit", err) } return }
func (s *UdpForwardServer) ListenAndServe() error { laddr, err := net.ResolveUDPAddr("udp", s.Base.Node.Addr) if err != nil { return err } raddr, err := net.ResolveUDPAddr("udp", s.Base.Node.Remote) if err != nil { return err } conn, err := net.ListenUDP("udp", laddr) if err != nil { glog.V(LWARNING).Infof("[udp] %s -> %s : %s", laddr, raddr, err) return err } defer conn.Close() if len(s.Base.Chain.nodes) == 0 { for { b := make([]byte, MediumBufferSize) n, addr, err := conn.ReadFromUDP(b) if err != nil { glog.V(LWARNING).Infof("[udp] %s -> %s : %s", laddr, raddr, err) continue } go func() { s.handleUdpForwardLocal(conn, addr, raddr, b[:n]) }() } } rChan, wChan := make(chan *gosocks5.UDPDatagram, 32), make(chan *gosocks5.UDPDatagram, 32) go func() { for { b := make([]byte, MediumBufferSize) n, addr, err := conn.ReadFromUDP(b) if err != nil { glog.V(LWARNING).Infof("[udp] %s -> %s : %s", laddr, raddr, err) return } select { case rChan <- gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(uint16(n), 0, ToSocksAddr(addr)), b[:n]): default: // glog.V(LWARNING).Infof("[udp-connect] %s -> %s : rbuf is full", laddr, raddr) } } }() go func() { for { dgram := <-wChan addr, err := net.ResolveUDPAddr("udp", dgram.Header.Addr.String()) if err != nil { glog.V(LWARNING).Infof("[udp] %s <- %s : %s", laddr, raddr, err) continue // drop silently } if _, err = conn.WriteToUDP(dgram.Data, addr); err != nil { glog.V(LWARNING).Infof("[udp] %s <- %s : %s", laddr, raddr, err) return } } }() for { s.handleUdpForwardTunnel(laddr, raddr, rChan, wChan) } }
func (s *RUdpForwardServer) connectRUdpForward(conn net.Conn, laddr, raddr *net.UDPAddr) error { glog.V(LINFO).Infof("[rudp] %s - %s", laddr, raddr) req := gosocks5.NewRequest(CmdUdpTun, ToSocksAddr(laddr)) conn.SetWriteDeadline(time.Now().Add(WriteTimeout)) if err := req.Write(conn); err != nil { glog.V(LWARNING).Infof("[rudp] %s -> %s : %s", laddr, raddr, err) return err } conn.SetWriteDeadline(time.Time{}) conn.SetReadDeadline(time.Now().Add(ReadTimeout)) rep, err := gosocks5.ReadReply(conn) if err != nil { glog.V(LWARNING).Infof("[rudp] %s <- %s : %s", laddr, raddr, err) return err } conn.SetReadDeadline(time.Time{}) if rep.Rep != gosocks5.Succeeded { glog.V(LWARNING).Infof("[rudp] %s <- %s : bind on %s failure", laddr, raddr, laddr) return errors.New(fmt.Sprintf("bind on %s failure", laddr)) } glog.V(LINFO).Infof("[rudp] %s - %s BIND ON %s OK", laddr, raddr, rep.Addr) for { dgram, err := gosocks5.ReadUDPDatagram(conn) if err != nil { glog.V(LWARNING).Infof("[rudp] %s <- %s : %s", laddr, raddr, err) return err } go func() { b := make([]byte, MediumBufferSize) relay, err := net.DialUDP("udp", nil, raddr) if err != nil { glog.V(LWARNING).Infof("[rudp] %s -> %s : %s", laddr, raddr, err) return } defer relay.Close() if _, err := relay.Write(dgram.Data); err != nil { glog.V(LWARNING).Infof("[rudp] %s -> %s : %s", laddr, raddr, err) return } glog.V(LDEBUG).Infof("[rudp] %s >>> %s length: %d", laddr, raddr, len(dgram.Data)) relay.SetReadDeadline(time.Now().Add(ReadTimeout)) n, err := relay.Read(b) if err != nil { glog.V(LWARNING).Infof("[rudp] %s <- %s : %s", laddr, raddr, err) return } relay.SetReadDeadline(time.Time{}) glog.V(LDEBUG).Infof("[rudp] %s <<< %s length: %d", laddr, raddr, n) conn.SetWriteDeadline(time.Now().Add(WriteTimeout)) if err := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(uint16(n), 0, dgram.Header.Addr), b[:n]).Write(conn); err != nil { glog.V(LWARNING).Infof("[rudp] %s <- %s : %s", laddr, raddr, err) return } conn.SetWriteDeadline(time.Time{}) }() } }