Sock 5 代理服务器

Stella981
• 阅读 653

package main
 
import (
     "net"
     "fmt"
     "io"
     "bytes"
     "encoding/binary"
)

type Methods struct{
    ver, nmethods uint8
    methods uint8
}

type sock5cmd struct{
    ver, cmd, rsv, atyp uint8
    dst [ 255]uint8
}

type proxyCoder struct {
    conn    net.Conn
}

func (c *proxyCoder) readMethods() Methods {
    var m Methods

    b : = make([] byte, 1024)
    n, err : = c.conn.Read(b)
     if err != nil && err != io.EOF { panic(err) }
    
    buf : = bytes.NewBuffer(b[ 0 :n])

    err = binary.Read(buf, binary.LittleEndian, &m.ver)
     if err != nil {
        fmt.Println( "binary.Read failed:", err)
    }
    
    err = binary.Read(buf, binary.LittleEndian, &m.nmethods)
     if err != nil {
        fmt.Println( "binary.Read failed:", err)
    }
    
    err = binary.Read(buf, binary.BigEndian, &m.methods)
     if err != nil {
        fmt.Println( "binary.Read failed:", err)
    }
    
     return m
}

func (c *proxyCoder) returnMethod() {
    buf : = make([] byte, 2)
    buf[ 0] = 5
    buf[ 1] = 0
    c.conn.Write(buf)
    fmt.Println(buf)
}

func (c *proxyCoder) serve() {
    buf : = make([] byte, 128)
    
    n, err : = c.conn.Read(buf)
     if err != nil && err != io.EOF { panic(err) }
    fmt.Println(buf[ :n])
    
    var s string
    var t string
    var i int
     if(buf[ 3] == 3){ //domail
         for i = 4; i < n - 2; i ++ {
            s += fmt.Sprintf( "%c", buf[i])
        }
    } else { //ip4 or ip6
        s += fmt.Sprintf( "%d", buf[ 4])
         for i = 5; i < n - 2; i ++ {
            s += fmt.Sprintf( ".%d", buf[i])
        }
    }
    
    p : = make([] byte, 2)
    var port uint16
    p[ 1] = buf[n - 1]
    p[ 0] = buf[n - 2]
    b : = bytes.NewBuffer(p)
    err = binary.Read(b, binary.BigEndian, &port)
     if err != nil {
        fmt.Println( "binary.Read failed:", err)
    }

    s += fmt.Sprintf( ":%d", port)

     switch buf[ 1] {
         case 1 : //TCP
            t = "tcp"
         case 2 : //BIND
         case 3 : //UDP
            t = "udp"
    }
    
    conn, err : = net.Dial(t, s)
     if err != nil {
        fmt.Printf( "%s connect error %s\n", t, s)
        buf[ 1] = 4
        c.conn.Write(buf[ :n])
        c.conn.Close()
         return
    }
    buf[ 1] = 0
    c.conn.Write(buf[ :n])
    fmt.Printf( "%s connect success %s\n", t, s)
    go serv(conn, c.conn)
    go serv(c.conn, conn)
}

func serv( in net.Conn, out net.Conn){
    b : = make([] byte, 10240)
     for ;;{
        n, err : = in.Read(b)
         if( err != nil ){
            fmt.Printf( "close\n")
             in.Close()
             out.Close()
             return
        }
        fmt.Printf( "serv %d\n", n)
         out.Write(b[ :n]);
    }

}

type Proxy struct {
}

func NewProxy() *Proxy {
     return &Proxy{}
}

var DefaultProxy = NewProxy()

func (p *Proxy) ProxyConn(conn net.Conn ){
    c : = &proxyCoder{conn}

    m : = c.readMethods()
    fmt.Println(m)
    
    c.returnMethod()
    
    c.serve()
}

func handleConnection(conn net.Conn){
    buf : = make([] byte, 1024)

    n, err : = conn.Read(buf)
     if err != nil && err != io.EOF { panic(err) }
    fmt.Println(buf[ :n])
    
     //answer
    buf[ 0] = 5
    buf[ 1] = 0
    conn.Write(buf[ : 2])
    fmt.Println(buf[ : 2])
    
     //serve
    n, err = conn.Read(buf)
     if err != nil && err != io.EOF { panic(err) }
    fmt.Println(buf[ :n])

    conn.Close()
}

func main() {
    ln, err : = net.Listen( "tcp", ":1080")
     if err != nil {
        fmt.Printf( "bind error\n")
         return
    }
     for {
        conn, err : = ln.Accept()
         if err != nil {
            fmt.Printf( "accept error\n")
             continue
        }
        go DefaultProxy.ProxyConn(conn)
         //go handleConnection(conn)
    }
}

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
风斗 风斗
3年前
Go 正则表达式
packagemainimport"bytes"import"fmt"import"regexp"funcmain(){//这个测试一个字符串是否符合一个表达式。match,_:regexp.MatchString("p(az)ch","peach")fmt.Println(match)//上面我们是直接使
Wesley13 Wesley13
3年前
go 协程
packageutilsimport("bytes""fmt""runtime""strconv")_/\__获取协程__ID\/_funcGetGoroutineID(){b:make(\\byte,64)b\b\:runtime.Stack(b,false)\b\
Stella981 Stella981
3年前
Go http访问使用代理
先写一段例子,例子是来自IRC gonuts的chentm,非常感谢他的帮助.packagemain import(    "fmt"    "net/http"    "net/url")funcmain(){    proxy:\func(\_\http.Requ
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
3年前
go并发基础数据加锁解锁
packagemain//go携程共享数据//加锁解锁操作//同步锁import("sync""fmt")funccomputed(dataint,locksync.Mutex){lock.Lock()//加锁霸占
Wesley13 Wesley13
3年前
Go语言中通过结构体匿名字段实现方法的继承和重载
Go语言中的结构体可以定义匿名字段。Go语言中没有对象,但是结构体却有大量对象的功能。并且用匿名字段的确可以实现对象的继承和重载。packagemain import "fmt"  typeA struct{     x int }  typeA1 struct{
Stella981 Stella981
3年前
Go正则提取html A 连接标签
import ("bufio""bytes""fmt""io/ioutil""net/http""os""regexp""strconv""strings")func ListHref(html string) {
Stella981 Stella981
3年前
Go语言JSON与Byte[]转化
记录下JSON与byte\\转化的操作,先来试试不存到文件的,当然要试试保存文件的,这样就可以保存配置信息了,JSON只是一种方式,XML的操作方法很类似,至于其他的方式以后再研究。packagemain  import(      "fmt"      "encoding/json" )