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