first commit
This commit is contained in:
commit
2502ef306f
117
gost.go
Normal file
117
gost.go
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
//"bufio"
|
||||||
|
//"bytes"
|
||||||
|
//"crypto/tls"
|
||||||
|
//"errors"
|
||||||
|
"io"
|
||||||
|
//"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
//"net/http"
|
||||||
|
//"strconv"
|
||||||
|
//"strings"
|
||||||
|
//"sync/atomic"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
readWait = 300 * time.Second
|
||||||
|
writeWait = 300 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
|
type Gost struct {
|
||||||
|
Laddr, Saddr, Proxy string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Gost) Run() error {
|
||||||
|
addr, err := net.ResolveTCPAddr("tcp", g.Laddr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ln, err := net.ListenTCP("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
conn, err := ln.AcceptTCP()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("accept:", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
go g.serve(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ln.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Gost) serve(conn net.Conn) error {
|
||||||
|
var pconn net.Conn
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
paddr, err := net.ResolveTCPAddr("tcp", g.Proxy)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
if paddr != nil {
|
||||||
|
pconn, err = net.DialTCP("tcp", nil, paddr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return g.foward(conn, pconn)
|
||||||
|
}
|
||||||
|
|
||||||
|
saddr, err := net.ResolveTCPAddr("tcp", g.Saddr)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
if saddr != nil {
|
||||||
|
sconn, err := net.DialTCP("tcp", nil, saddr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer sconn.Close()
|
||||||
|
|
||||||
|
return g.transport(conn, sconn)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Gost) foward(conn, pconn net.Conn) error {
|
||||||
|
defer pconn.Close()
|
||||||
|
|
||||||
|
saddr, err := net.ResolveTCPAddr("tcp", g.Saddr)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if saddr != nil {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Gost) pipe(src io.Reader, dst io.Writer, c chan<- error) {
|
||||||
|
_, err := io.Copy(dst, src)
|
||||||
|
c <- err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Gost) transport(conn net.Conn, conn2 net.Conn) (err error) {
|
||||||
|
rChan := make(chan error, 1)
|
||||||
|
wChan := make(chan error, 1)
|
||||||
|
|
||||||
|
go g.pipe(conn, conn2, wChan)
|
||||||
|
go g.pipe(conn2, conn, rChan)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case err = <-wChan:
|
||||||
|
case err = <-rChan:
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
22
main.go
Normal file
22
main.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// main
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var gost Gost
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flag.StringVar(&gost.Proxy, "P", "", "proxy for forward")
|
||||||
|
flag.StringVar(&gost.Saddr, "S", "", "the server that connecting to")
|
||||||
|
flag.StringVar(&gost.Laddr, "L", ":8080", "listen address")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log.Fatal(gost.Run())
|
||||||
|
}
|
167
socks5.go
Normal file
167
socks5.go
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
Ver5 = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MethodNoAuth uint8 = iota
|
||||||
|
MethodGSSAPI
|
||||||
|
MethodUserPass
|
||||||
|
// X'03' to X'7F' IANA ASSIGNED
|
||||||
|
// X'80' to X'FE' RESERVED FOR PRIVATE METHODS
|
||||||
|
MethodNoAcceptable = 0xFF
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CmdConnect uint8 = 1
|
||||||
|
CmdBind = 2
|
||||||
|
CmdUdp = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AddrIPv4 uint8 = 1
|
||||||
|
AddrDomain = 3
|
||||||
|
AddrIPv6 = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
Succeeded uint8 = iota
|
||||||
|
Failure
|
||||||
|
NotAllowed
|
||||||
|
NetUnreachable
|
||||||
|
HostUnreachable
|
||||||
|
ConnRefused
|
||||||
|
TTLExpired
|
||||||
|
CmdUnsupported
|
||||||
|
AddrUnsupported
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrBadVersion = errors.New("Bad version")
|
||||||
|
ErrBadFormat = errors.New("Bad format")
|
||||||
|
ErrBadAddrType = errors.New("Bad address type")
|
||||||
|
ErrShortBuffer = errors.New("Short buffer")
|
||||||
|
|
||||||
|
cmdErrMap = map[uint8]error{
|
||||||
|
Failure: errors.New("General SOCKS server failure"),
|
||||||
|
NotAllowed: errors.New("Connection not allowed by ruleset"),
|
||||||
|
NetUnreachable: errors.New("Network unreachable"),
|
||||||
|
HostUnreachable: errors.New("Host unreachable"),
|
||||||
|
ConnRefused: errors.New("Connection refused"),
|
||||||
|
TTLExpired: errors.New("TTL expired"),
|
||||||
|
CmdUnsupported: errors.New("Command not supported"),
|
||||||
|
AddrUnsupported: errors.New("Address type not supported"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
+----+-----+-------+------+----------+----------+
|
||||||
|
|VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
|
||||||
|
+----+-----+-------+------+----------+----------+
|
||||||
|
| 1 | 1 | X'00' | 1 | Variable | 2 |
|
||||||
|
+----+-----+-------+------+----------+----------+
|
||||||
|
*/
|
||||||
|
type Cmd struct {
|
||||||
|
Cmd uint8
|
||||||
|
AddrType uint8
|
||||||
|
Addr string
|
||||||
|
Port uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCmd(cmd uint8, atype uint8, addr string, port uint16) *Cmd {
|
||||||
|
return &Cmd{
|
||||||
|
Cmd: cmd,
|
||||||
|
AddrType: atype,
|
||||||
|
Addr: addr,
|
||||||
|
Port: port,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadCmd(r io.Reader) (*Cmd, error) {
|
||||||
|
b := make([]byte, 256)
|
||||||
|
n, err := r.Read(b)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if n < 10 {
|
||||||
|
return nil, ErrBadFormat
|
||||||
|
}
|
||||||
|
if b[0] != Ver5 {
|
||||||
|
return nil, ErrBadVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := &Cmd{
|
||||||
|
Cmd: b[1],
|
||||||
|
AddrType: b[3],
|
||||||
|
}
|
||||||
|
|
||||||
|
pos := 4
|
||||||
|
|
||||||
|
switch cmd.AddrType {
|
||||||
|
case AddrIPv4:
|
||||||
|
if n != 10 {
|
||||||
|
return nil, ErrBadFormat
|
||||||
|
}
|
||||||
|
cmd.Addr = net.IP(b[pos : pos+4]).String()
|
||||||
|
pos += 4
|
||||||
|
case AddrIPv6:
|
||||||
|
if n != 22 {
|
||||||
|
return nil, ErrBadFormat
|
||||||
|
}
|
||||||
|
cmd.Addr = net.IP(b[pos : pos+16]).String()
|
||||||
|
pos += 16
|
||||||
|
case AddrDomain:
|
||||||
|
length := int(b[pos])
|
||||||
|
if n != 4+1+length+2 {
|
||||||
|
return nil, ErrBadFormat
|
||||||
|
}
|
||||||
|
|
||||||
|
pos++
|
||||||
|
cmd.Addr = string(b[pos : pos+length])
|
||||||
|
pos += length
|
||||||
|
default:
|
||||||
|
return nil, ErrBadAddrType
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Port = binary.BigEndian.Uint16(b[pos:])
|
||||||
|
|
||||||
|
return cmd, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *Cmd) Write(w io.Writer) (err error) {
|
||||||
|
b := make([]byte, 256)
|
||||||
|
|
||||||
|
b[0] = Ver5
|
||||||
|
b[1] = cmd.Cmd
|
||||||
|
b[3] = cmd.AddrType
|
||||||
|
pos := 4
|
||||||
|
|
||||||
|
switch cmd.AddrType {
|
||||||
|
case AddrIPv4:
|
||||||
|
pos += copy(b[pos:], net.ParseIP(cmd.Addr).To4())
|
||||||
|
case AddrDomain:
|
||||||
|
b[pos] = byte(len(cmd.Addr))
|
||||||
|
pos++
|
||||||
|
pos += copy(b[pos:], []byte(cmd.Addr))
|
||||||
|
case AddrIPv6:
|
||||||
|
pos += copy(b[pos:], net.ParseIP(cmd.Addr).To16())
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(b[pos:], cmd.Port)
|
||||||
|
pos += 2
|
||||||
|
|
||||||
|
_, err = w.Write(b[:pos])
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *Cmd) GetError() error {
|
||||||
|
return cmdErrMap[cmd.Cmd]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user