Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
本次merge,修复了udp在加密时不可用的错误。
  • Loading branch information
GuoYuefei committed Aug 15, 2019
2 parents 71d073f + 4f7d45a commit 1b4657a
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 68 deletions.
2 changes: 1 addition & 1 deletion bard-plugin
15 changes: 7 additions & 8 deletions bard/TCSubProtocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"io"
"net"
"os"
"path/filepath"
"plugin"
Expand All @@ -24,10 +23,10 @@ var SubProtocol_ZERO = errors.New("No valid SubProtocol Plugin under the folder

type TCSPReadDo interface {
// @describe 根据协议从conn中读取控制信息
// @param conn net.Conn 可以读取的连接
// @param conn io.Reader 可以读取的连接
// @return []byte 本函数从conn中读取的内容
// @return uint 得到接下来数据包的长度
ReadDo(conn net.Conn) ([]byte, int)
ReadDo(conn io.Reader) ([]byte, int)
}

type TCSPWriteDo interface {
Expand Down Expand Up @@ -114,13 +113,13 @@ func SubProtocolsFromDir(subProtocolsPath string) (ts *TCSubProtocols, e error)
}

// 一个默认的TCSubProtocol的Do函数
func DefaultTCSPReadDo(conn net.Conn) ([]byte, int) {
func DefaultTCSPReadDo(reader io.Reader) ([]byte, int) {
// default len is two byte
lslice := make([]byte, 2)
_, err := ReadFull(conn, lslice)
//fmt.Println("err:", err)
if err != nil && err != io.EOF {
//fmt.Println("readdo readfull")
_, err := io.ReadFull(reader, lslice)
//fmt.Println("err:", err) && err != io.EOF
if err != nil {
//fmt.Println(err)
return nil, 0
}
// 大端
Expand Down
17 changes: 15 additions & 2 deletions bard/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ Write:
func (c *Conn) Read(b []byte) (n int, err error) {
// 如果没插件那就正常读取
if c.plugin == nil {
if c.protocol != nil {
_, n = c.protocol.ReadDo(c.Conn)

if n == 0 {
return 0, errors.New("read package len error or io.EOF")
}
// 这里的protocol没有用处(无plugin),仅处理好控制信息,但是对读取信息过程不影响
}
n, err = c.Conn.Read(b)
_ = c.SetDeadline(c.GetDeadline())
return
Expand All @@ -139,9 +147,14 @@ func (c *Conn) Read(b []byte) (n int, err error) {
}
}

// io.EOF会返回[0,0], 0. 其他错误nil, 0
_, n = c.protocol.ReadDo(c.Conn)
if c.protocol == nil {
// 在有plugin下,必须配置子协议
panic("conn read: Subprotocols must be configured in the presence of plug-ins")
}

// io.EOF和其他错误[], 0
_, n = c.protocol.ReadDo(c.Conn)
//fmt.Println(do, n)
if n == 0 {
return 0, errors.New("read package len error or io.EOF")
}
Expand Down
3 changes: 1 addition & 2 deletions bard/pcqi.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package bard

import (
"errors"
"fmt"
"net"
"strconv"
"sync"
Expand Down Expand Up @@ -49,7 +48,7 @@ func (p *PCQInfo) Response(conn *Conn, server string) error {
// 主要响应socks5最后的请求 cmd 为udp
// 服务器端server 一般只有一个ip todo 先别管多IP吧 而且还只支持ipv4
var ip = net.ParseIP(server)
fmt.Println("ip is .............", ip.To4())
//fmt.Println("ip is .............", ip.To4())
// 遵照回应udp的写法
resp = append([]byte{0x05, 0x00, 0x00, 0x01}, ip.To4()...)
resp = append(resp, p.Dst.Port[0], p.Dst.Port[1]+2)
Expand Down
4 changes: 2 additions & 2 deletions bard/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func ServerHandShake(r *bufio.Reader, conn net.Conn, config *Config) (error, *Co
Logf("Connection request from client IP %v, permission authentication failed", conn.RemoteAddr())
}

// endtodo 丢弃缓冲区中所有内容,准备下轮对话
// 丢弃缓冲区中所有内容,准备下轮对话
r.Reset(conn)
_, err = conn.Write(resp)
if err != nil {
Expand Down Expand Up @@ -127,7 +127,7 @@ func CommConfigRegisterToConn(conn *Conn, config *CommConfig, plugins *Plugins,
}
}

// node 只有配置了传输控制子协议才能注册
// 只有配置了传输控制子协议才能注册
if protocol != nil {
if len(ps.Pmap) != 0 {
conn.Register(ps.ToBigIPlugin(), protocol)
Expand Down
30 changes: 17 additions & 13 deletions bard/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ type Client struct {
LocalConn *Conn
//CSMessage chan *Message

PCQI *PCQInfo // node 这是LocalConn得到的请求 这个内容其实只要原封不动传给远程代理就行
PCQI *PCQInfo // 这是LocalConn得到的请求 这个内容其实只要原封不动传给远程代理就行
// todo 以下addr需要改成PCRspInfo类型
PCRsp *PCRspInfo // node 这是RemoteConn远程服务器发回的响应 服务器返回响应,仅udp代理时有用,先不考虑udp
PCRsp *PCRspInfo // 这是RemoteConn远程服务器发回的响应 服务器返回响应,仅udp代理时有用

//SCMessage chan *Message
RemoteConn *Conn
Expand Down Expand Up @@ -59,41 +59,44 @@ func (c *Client)Pipe() {
func (c *Client)PipeUdp() {
// do something with udp channel
//remoteUdpAddr, err := net.ResolveUDPAddr("udp", c.PCRsp.SAddr.AddrString())
localUdpAddr, err := net.ResolveUDPAddr("udp", c.config.GetLocalString()+":"+
localUdpAddr, err := net.ResolveUDPAddr("udp", ":"+
strconv.Itoa(c.PCQI.Dst.PortToInt()+2))
if err != nil {
Deb.Println("UDP parse error,", err)
Logln("UDP addr parse error,", err)
return
}
// node 这个udpPacket是客户端处理一个udp连接时的唯一通道,包括与客户端的客户端通讯和客户端的服务器端
localPacket, err := net.ListenUDP("udp", localUdpAddr)
if err != nil {
Deb.Println(err)
Logln(err)
RefuseRequest(c.LocalConn)
return
}
err = c.PCQI.Response(c.LocalConn, c.config.GetLocalString())

if err != nil {
Deb.Println(err)
Logln(err)
//RefuseRequest(c.LocalConn) // 没回复成功成功,不知要不要回复失败,因为可能回复失败也失败
return
}

// c.RemoteConn 主要是把含有plugin的一个连接传入 此时Packet类型中的client就是远程代理服务器的监听地址了。 因为udp交流是双方是平等的,也可以将远程服务器理解成本udp连接的客户端
packet, e := NewPacket(/*c.LocalConn*/c.RemoteConn, localPacket, c.PCRsp.SAddr.PortToInt())
if e != nil {
Logln(e)
return
}
packet.SetTimeout(c.config.Timeout)
if addr, ok := c.LocalConn.RemoteAddr().(*net.TCPAddr); ok {
udpAddr, err := net.ResolveUDPAddr("udp", addr.IP.String()+":"+strconv.Itoa(c.PCQI.Dst.PortToInt()))
if err != nil {
Logln(e)
return
}
packet.AddServer("local", udpAddr)
} else {
Deb.Println("c.LocalConn.RemoteAddr() is not a TCPAddr")
Logln("c.LocalConn.RemoteAddr() is not a TCPAddr")
return
}
wg := new(sync.WaitGroup)
wg. Add(2)
Expand All @@ -109,7 +112,7 @@ func (c *Client)PipeUdp() {
err = packet.ListenToFixedTarget("local")
if err != nil {
// 记录到日志 可能以后会出现其他错误 如果只是udp关闭的话就是正确的逻辑
Slog.Println("packet.listen close:", err)
Logln("packet.listen close:", err)
close(packet.message)
break
}
Expand All @@ -126,7 +129,7 @@ func (c *Client)PipeUdp() {
}
_, err = packet.Request()
if err != nil {
Slog.Println("packet.request close:", err)
Logln("packet.request close:", err)
break
}
}
Expand All @@ -140,7 +143,7 @@ func (c *Client)PipeTcp() {
wg.Add(2)
e := c.PCQI.Response(c.LocalConn, c.config.GetLocalString())
if e != nil {
Deb.Println(e)
Logln(e)
c.Close()
wg.Done(); wg.Done() // 发生错误还需要解锁的
return
Expand Down Expand Up @@ -187,7 +190,6 @@ func (c *Client)PipeTcp() {
/**
定义Client的能力
1、可以根据配置文件连接远程代理服务器,做到第一次握手
2、初始化两个Message的通道
-------------以上应该在初始化时完成----------------
3、两个conn各自对自己的通道操作。 每个函数2协程
4、外层调用,开两个协程。 over 一共一次连接7协程
Expand All @@ -196,6 +198,8 @@ func (c *Client)PipeTcp() {
@param localConn 一定要是已经建立起本地socks5连接的conn
@param pcqi 是localConn接收到的请求信息
@param config 配置文件信息
@param plugins 插件信息集
@param protocols 子协议集
*/
func NewClient(localConn *Conn, pcqi *PCQInfo, config *Config, plugins *Plugins, protocols *TCSubProtocols) (c *Client, err error){
c = &Client{}
Expand Down Expand Up @@ -254,7 +258,7 @@ func ClientHandleShakeWithRemote(r *bufio.Reader, conn *Conn, pcqi *PCQInfo, con

if b != SocksVersion {
e = ErrorSocksVersion
Deb.Println("version byte is", b)
//Deb.Println("version byte is", b)
return
}
method, e := r.ReadByte()
Expand All @@ -275,7 +279,7 @@ func ClientHandleShakeWithRemote(r *bufio.Reader, conn *Conn, pcqi *PCQInfo, con
}
r.Reset(conn) // 清空缓存

// node 在发送请求前需要重新注册通讯配置信息
// 在发送请求前需要重新注册通讯配置信息
ok := CommConfigRegisterToConn(conn, config.Users[0].ComConfig, plugins, protocols)
if !ok {
e = errors.New("User Communication Configuration Not Found! ")
Expand Down
Loading

0 comments on commit 1b4657a

Please sign in to comment.