mirror of
https://github.com/xjasonlyu/tun2socks.git
synced 2025-10-28 10:51:45 +08:00
mainly update
This commit is contained in:
101
proxy/socks/client.go
Executable file
101
proxy/socks/client.go
Executable file
@@ -0,0 +1,101 @@
|
||||
package socks
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
var tcpTimeout = 30 * time.Second
|
||||
|
||||
func Dial(proxy, target string) (net.Conn, error) {
|
||||
c, err := net.DialTimeout("tcp", proxy, tcpTimeout)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error", proxy)
|
||||
}
|
||||
|
||||
if _, err := ClientHandshake(c, ParseAddr(target), CmdConnect); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func DialUDP(proxy, target string) (_ net.PacketConn, _ net.Addr, err error) {
|
||||
c, err := net.DialTimeout("tcp", proxy, tcpTimeout)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%s connect error", proxy)
|
||||
return
|
||||
}
|
||||
|
||||
// tcp set keepalive
|
||||
c.(*net.TCPConn).SetKeepAlive(true)
|
||||
c.(*net.TCPConn).SetKeepAlivePeriod(tcpTimeout)
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
c.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
bindAddr, err := ClientHandshake(c, ParseAddr(target), CmdUDPAssociate)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%v client hanshake error", err)
|
||||
return
|
||||
}
|
||||
|
||||
addr, err := net.ResolveUDPAddr("udp", bindAddr.String())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
targetAddr, err := net.ResolveUDPAddr("udp", target)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
pc, err := net.ListenPacket("udp", "")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
io.Copy(ioutil.Discard, c)
|
||||
c.Close()
|
||||
// A UDP association terminates when the TCP connection that the UDP
|
||||
// ASSOCIATE request arrived on terminates. RFC1928
|
||||
pc.Close()
|
||||
}()
|
||||
|
||||
return &socksUDPConn{PacketConn: pc, tcpConn: c, targetAddr: targetAddr}, addr, nil
|
||||
}
|
||||
|
||||
type socksUDPConn struct {
|
||||
net.PacketConn
|
||||
tcpConn net.Conn
|
||||
targetAddr net.Addr
|
||||
}
|
||||
|
||||
func (c *socksUDPConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
|
||||
packet, err := EncodeUDPPacket(c.targetAddr.String(), b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return c.PacketConn.WriteTo(packet, addr)
|
||||
}
|
||||
|
||||
func (c *socksUDPConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||
n, a, e := c.PacketConn.ReadFrom(b)
|
||||
addr, payload, err := DecodeUDPPacket(b)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
copy(b, payload)
|
||||
return n - len(addr) - 3, a, e
|
||||
}
|
||||
|
||||
func (c *socksUDPConn) Close() error {
|
||||
c.tcpConn.Close()
|
||||
return c.PacketConn.Close()
|
||||
}
|
||||
Reference in New Issue
Block a user