func (r *relayHandler) ServeSocks(conn *gosocks.SocksConn) { conn.SetReadDeadline(time.Now().Add(conn.Timeout)) req, err := gosocks.ReadSocksRequest(conn) if err != nil { log.Printf("error in ReadSocksRequest: %s", err) return } switch req.Cmd { case gosocks.SocksCmdConnect: chain := r.lookup(req.DstHost, conn) if chain != nil { chain.TCP(req, conn) } else { r.basic.HandleCmdConnect(req, conn) } return case gosocks.SocksCmdUDPAssociate: r.handleUDPAssociate(req, conn) return case gosocks.SocksCmdBind: conn.Close() return default: return } }
func (srv *server) transactBegin(s *session, w http.ResponseWriter, req *http.Request) error { body := http.MaxBytesReader(w, req.Body, maxPayloadLength+1) dialer := &gosocks.SocksDialer{ Timeout: socksTimeout, Auth: &gosocks.AnonymousClientAuthenticator{}, } conn, err := dialer.Dial(srv.socksAddr) if err != nil { meekResponse(w, "Internal server error", []byte("")) return err } // I am sure that this is a TCPConn conn.Conn.(*net.TCPConn).SetReadBuffer(socksReadBufSize) s.tc = conn socksReq, err := gosocks.ReadSocksRequest(body) if socksReq.Cmd == gosocks.SocksCmdUDPAssociate { // if cmd is UDP_ASSOCIATE, no restriction on sending address socksReq.HostType = gosocks.SocksIPv4Host socksReq.DstHost = "0.0.0.0" socksReq.DstPort = 0 } if err != nil { meekResponse(w, "Bad request", []byte("")) return fmt.Errorf("invalid socks request: %s", err) } socksReply, err := gosocks.ClientRequest(s.tc, socksReq) if err != nil || socksReply.Rep != gosocks.SocksSucceeded { meekResponse(w, "Internal server error", []byte("")) return err } log.Printf("[%s] cmd 0x%02x with DstAddr: %s:%d", s.remoteAddr, socksReq.Cmd, socksReq.DstHost, socksReq.DstPort) if socksReq.Cmd == gosocks.SocksCmdUDPAssociate { uc, err := net.Dial("udp", gosocks.SockAddrString(socksReply.BndHost, socksReply.BndPort)) if err != nil { meekResponse(w, "Internal server error", []byte("")) return err } s.uc = uc.(*net.UDPConn) s.uc.SetReadBuffer(socksReadBufSize) } gosocks.WriteSocksReply(w, socksReply) return nil }