Example #1
0
func cliTunnelUDP(uconn *net.UDPConn, sconn net.Conn) {
	var raddr *net.UDPAddr

	go func() {
		b := lpool.Take()
		defer lpool.put(b)

		for {
			n, addr, err := uconn.ReadFromUDP(b)
			if err != nil {
				log.Println(err)
				return
			}
			raddr = addr
			r := bytes.NewBuffer(b[:n])
			udp, err := gosocks5.ReadUDPDatagram(r)
			if err != nil {
				return
			}
			udp.Header.Rsv = uint16(len(udp.Data))
			//log.Println("r", raddr.String(), udp.Header)

			if err := udp.Write(sconn); err != nil {
				log.Println(err)
				return
			}
		}
	}()

	for {
		b := lpool.Take()
		defer lpool.put(b)

		udp, err := gosocks5.ReadUDPDatagram(sconn)
		if err != nil {
			log.Println(err)
			return
		}
		//log.Println("w", udp.Header)
		udp.Header.Rsv = 0
		buf := bytes.NewBuffer(b[0:0])
		udp.Write(buf)
		if _, err := uconn.WriteTo(buf.Bytes(), raddr); err != nil {
			log.Println(err)
			return
		}
	}
}
Example #2
0
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{})
		}()
	}
}
Example #3
0
func createClientConn(conn net.Conn, uconn *net.UDPConn) (c *UDPConn, dgram *gosocks5.UDPDatagram, err error) {
	var raddr *net.UDPAddr
	dgramChan := make(chan *gosocks5.UDPDatagram, 1)
	errChan := make(chan error, 1)
	go func() {
		b := make([]byte, 64*1024+262)

		n, addr, err := uconn.ReadFromUDP(b)
		if err != nil {
			errChan <- err
			return
		}
		raddr = addr

		dgram, err := gosocks5.ReadUDPDatagram(bytes.NewReader(b[:n]))
		if err != nil {
			errChan <- err
			return
		}
		dgramChan <- dgram
	}()

	go func() {
		dgram, err := gosocks5.ReadUDPDatagram(conn)
		if err != nil {
			errChan <- err
			return
		}
		dgramChan <- dgram
	}()

	select {
	case dgram = <-dgramChan:
		if raddr != nil {
			glog.V(LINFO).Infoln("[udp] client", raddr)
			c = Client(uconn, raddr)
		} else {
			glog.V(LINFO).Infoln("[udp] tunnel")
			c = Client(conn, nil)
		}
	case err = <-errChan:
	}

	return
}
Example #4
0
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)
}
Example #5
0
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
		}
	}
}
Example #6
0
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
		}
	}
}
Example #7
0
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
}
Example #8
0
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
}
Example #9
0
func (c *UDPConn) readUDPClient() (*gosocks5.UDPDatagram, error) {
	if c.udp != nil {
		return gosocks5.ReadUDPDatagram(c.udp)
	}
	return gosocks5.ReadUDPDatagram(c.tcp)
}
Example #10
0
func handleSocks5Request(req *gosocks5.Request, conn net.Conn) {
	glog.V(LDEBUG).Infoln(req)

	switch req.Cmd {
	case gosocks5.CmdConnect:
		glog.V(LINFO).Infoln("[socks5] CONNECT", req.Addr)

		tconn, err := Connect(req.Addr.String())
		if err != nil {
			glog.V(LWARNING).Infoln("[socks5] CONNECT", req.Addr, err)
			rep := gosocks5.NewReply(gosocks5.HostUnreachable, nil)
			if err := rep.Write(conn); err != nil {
				glog.V(LWARNING).Infoln("socks5 connect:", err)
			} else {
				glog.V(LDEBUG).Infoln(rep)
			}
			return
		}
		defer tconn.Close()

		rep := gosocks5.NewReply(gosocks5.Succeeded, nil)
		if err := rep.Write(conn); err != nil {
			glog.V(LWARNING).Infoln("socks5 connect:", err)
			return
		}
		glog.V(LDEBUG).Infoln(rep)

		glog.V(LINFO).Infoln("[socks5] CONNECT", req.Addr, "OK")
		Transport(conn, tconn)
	case gosocks5.CmdBind:
		glog.V(LINFO).Infoln("[socks5] BIND", req.Addr)

		if len(forwardArgs) > 0 {
			forwardBind(req, conn)
		} else {
			serveBind(conn)
		}
	case gosocks5.CmdUdp, CmdUdpTun:
		glog.V(LINFO).Infoln("[socks5] UDP ASSOCIATE", req.Addr)
		uconn, err := net.ListenUDP("udp", nil)
		if err != nil {
			glog.V(LWARNING).Infoln("socks5 udp listen:", err)

			rep := gosocks5.NewReply(gosocks5.Failure, nil)
			if err := rep.Write(conn); err != nil {
				glog.V(LWARNING).Infoln("socks5 udp listen:", err)
			} else {
				glog.V(LDEBUG).Infoln(rep)
			}
			return
		}
		defer uconn.Close()

		addr := ToSocksAddr(uconn.LocalAddr())
		addr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String())

		rep := gosocks5.NewReply(gosocks5.Succeeded, addr)
		if err := rep.Write(conn); err != nil {
			glog.V(LWARNING).Infoln("socks5 udp:", err)
			return
		} else {
			glog.V(LDEBUG).Infoln(rep)
			glog.V(LINFO).Infoln("[socks5] UDP listen on", addr)
		}

		var cc *UDPConn
		var dgram *gosocks5.UDPDatagram
		if req.Cmd == CmdUdpTun {
			dgram, err = gosocks5.ReadUDPDatagram(conn)
			if err != nil {
				glog.V(LWARNING).Infoln("socks5 udp:", err)
				return
			}
			cc = Client(conn, nil)
			glog.V(LINFO).Infof("[udp] -> %s, length %d", dgram.Header.Addr, len(dgram.Data))
		} else {
			b := udpPool.Get().([]byte)
			defer udpPool.Put(b)

			n, raddr, err := uconn.ReadFromUDP(b)
			if err != nil {
				glog.V(LWARNING).Infoln("socks5 udp:", err)
				return
			}
			dgram, err = gosocks5.ReadUDPDatagram(bytes.NewReader(b[:n]))
			if err != nil {
				glog.V(LWARNING).Infoln("socks5 udp:", err)
				return
			}
			cc = Client(uconn, raddr)
			glog.V(LINFO).Infof("[udp] %s -> %s, length %d", raddr, dgram.Header.Addr, len(dgram.Data))
		}

		sc, err := createServerConn(uconn)
		if err != nil {
			glog.V(LWARNING).Infoln("socks5 udp:", err)
			return
		}
		defer sc.Close()

		if err = sc.WriteUDPTimeout(dgram, time.Second*90); err != nil {
			glog.V(LWARNING).Infoln("socks5 udp:", err)
			return
		}
		dgram, err = sc.ReadUDPTimeout(time.Second * 90)
		if err != nil {
			glog.V(LWARNING).Infoln("socks5 udp:", err)
			return
		}
		glog.V(LINFO).Infof("[udp] <- %s, length %d", dgram.Header.Addr, len(dgram.Data))

		if err = cc.WriteUDPTimeout(dgram, time.Second*90); err != nil {
			glog.V(LWARNING).Infoln("socks5 udp:", err)
			return
		}

		if req.Cmd == gosocks5.CmdUdp {
			go TransportUDP(cc, sc)
			ioutil.ReadAll(conn) // wait for client exit
			glog.V(LINFO).Infoln("[udp] transfer done")
		} else {
			TransportUDP(cc, sc)
		}
	default:
		glog.V(LWARNING).Infoln("Unrecognized request: ", req)
	}
}
Example #11
0
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{})
		}()
	}
}
Example #12
0
func (s *UdpForwardServer) handleUdpForwardTunnel(laddr, raddr *net.UDPAddr, rChan, wChan chan *gosocks5.UDPDatagram) {
	var cc net.Conn
	var err error
	retry := 0

	for {
		cc, err = s.prepareUdpConnectTunnel(raddr)
		if err != nil {
			glog.V(LWARNING).Infof("[udp] %s -> %s : %s", laddr, raddr, err)
			time.Sleep((1 << uint(retry)) * time.Second)
			if retry < 5 {
				retry++
			}
			continue
		}
		break
	}
	defer cc.Close()

	glog.V(LINFO).Infof("[udp] %s <-> %s", laddr, raddr)

	rExit := make(chan interface{})
	errc := make(chan error, 2)

	go func() {
		for {
			select {
			case dgram := <-rChan:
				if err := dgram.Write(cc); err != nil {
					glog.V(LWARNING).Infof("[udp] %s -> %s : %s", laddr, raddr, err)
					errc <- err
					return
				}
				glog.V(LDEBUG).Infof("[udp-tun] %s >>> %s length: %d", laddr, raddr, len(dgram.Data))
			case <-rExit:
				// glog.V(LDEBUG).Infof("[udp-connect] %s -> %s : exited", laddr, raddr)
				return
			}
		}
	}()
	go func() {
		for {
			dgram, err := gosocks5.ReadUDPDatagram(cc)
			if err != nil {
				glog.V(LWARNING).Infof("[udp] %s <- %s : %s", laddr, raddr, err)
				close(rExit)
				errc <- err
				return
			}

			select {
			case wChan <- dgram:
				glog.V(LDEBUG).Infof("[udp-tun] %s <<< %s length: %d", laddr, raddr, len(dgram.Data))
			default:
			}
		}
	}()

	select {
	case <-errc:
		//log.Println("w exit", err)
	}
	glog.V(LINFO).Infof("[udp] %s >-< %s", laddr, raddr)
}