Skip to content

Commit

Permalink
ipn/socks5: wrap socks5 conn into core/proto
Browse files Browse the repository at this point in the history
  • Loading branch information
ignoramous committed Oct 21, 2023
1 parent 9d57d25 commit 67eb604
Showing 1 changed file with 45 additions and 7 deletions.
52 changes: 45 additions & 7 deletions intra/ipn/socks5.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
package ipn

import (
"net"
"net/http"

"github.com/celzero/firestack/intra/core"
"github.com/celzero/firestack/intra/dialers"
"github.com/celzero/firestack/intra/log"
"github.com/celzero/firestack/intra/protect"
Expand All @@ -25,6 +27,41 @@ type socks5 struct {
status int
}

type socks5tcpconn struct {
*tx.Client
}

type socks5udpconn struct {
*tx.Client
}

var _ core.TCPConn = (*socks5tcpconn)(nil)
var _ core.UDPConn = (*socks5udpconn)(nil)

func (c *socks5tcpconn) CloseRead() error {
return c.Close()
}

func (c *socks5tcpconn) CloseWrite() error {
return c.Close()
}

func (c *socks5udpconn) Ready() bool {
return c.Client != nil && c.Client.UDPConn != nil
}

// WriteFrom writes b to TUN using addr as the source.
func (c *socks5udpconn) WriteFrom(b []byte, addr *net.UDPAddr) (int, error) {
// no-op; intra/udp.go does not require outbound udp to implement TUN specific methods
return 0, nil
}

// ReceiveTo is incoming TUN packet b to be sent to addr.
func (c *socks5udpconn) ReceiveTo(b []byte, addr *net.UDPAddr) error {
// no-op; intra/udp.go does not require outbound udp to implement TUN specific methods
return nil
}

func NewSocks5Proxy(id string, ctl protect.Controller, po *settings.ProxyOptions) (Proxy, error) {
var err error
if po == nil {
Expand Down Expand Up @@ -65,30 +102,31 @@ func (h *socks5) Dial(network, addr string) (c protect.Conn, err error) {
return nil, errProxyStopped
}

log.D("proxy: socks5: %d dial(%s) from %s -> %s", h.ID(), network, h.GetAddr(), addr)
// tx.Client.Dial does not support dialing hostnames
if c, err = dialers.ProxyDial(h.proxydialer, network, addr); err == nil {
// in txthinking/socks5, an underlying-conn is actually a net.TCPConn
// github.com/txthinking/socks5/blob/39268fae/client.go#L15
if uc, ok := c.(*tx.Client); ok {
if uc.TCPConn != nil {
c = uc.TCPConn
c = &socks5tcpconn{uc}
} else if uc.UDPConn != nil {
c = uc.UDPConn
c = &socks5udpconn{uc}
} else {
log.W("proxy: socks5 conn not tcp nor udp %s -> %s", h.GetAddr(), addr)
log.W("proxy: socks5: %s conn not tcp nor udp %s -> %s", h.ID(), h.GetAddr(), addr)
c = nil
err = errNoProxyConn
}
} else {
log.W("proxy: socks5 conn not a tx.Client(%s) %s -> %s", network, h.GetAddr(), addr)
log.W("proxy: socks5: %s conn not a tx.Client(%s) %s -> %s", h.ID(), network, h.GetAddr(), addr)
c = nil
err = errNoProxyConn
}
} else {
log.W("proxy: socks5 dial(%s) failed %s -> %s: %v", network, h.GetAddr(), addr, err)
log.W("proxy: socks5: %s dial(%s) failed %s -> %s: %v", h.ID(), network, h.GetAddr(), addr, err)
}
if err == nil {
log.I("proxy: socks5: dial(%s) from %s -> %s", network, h.GetAddr(), addr)
log.I("proxy: socks5: %s dial(%s) from %s -> %s", h.ID(), network, h.GetAddr(), addr)
h.status = TOK
} else {
h.status = TKO
Expand All @@ -106,7 +144,7 @@ func (h *socks5) DNS() string {

func (h *socks5) fetch(req *http.Request) (*http.Response, error) {
stopped := h.status == END
log.V("proxy: socks5: %s; fetch(%s); ok? %t", h.id, req.URL, !stopped)
log.V("proxy: socks5: %s; fetch(%s); ended? %t", h.id, req.URL, stopped)
if stopped {
return nil, errProxyStopped
}
Expand Down

0 comments on commit 67eb604

Please sign in to comment.