Files
v2ray_simple/proxy/socks5http/server.go
e1732a364fed a9a746ba2f 多项对接口的修改,为ss做准备:
取消Client的LocalAddr,改为 LocalTCPAddr 和 LocalUDPAddr
删除direct中的对应条目。这样可更清晰地配置双本地地址

将设置sendthrough设置双地址的代码移动到 proxy.newClient函数

这样不仅direct可指定不同的tcp和udp的本地地址,任何client协议都可以了

为ClientCreator 接口 添加 UseUDPAsMsgConn 方法,direct和ss返回true

在ss的client的EstablishUDPChannel进行自行拨号

在ss的server建立后,自动循环监听udp,绕过vs的基本监听机制。因为vs架构的限制,一个代理只能有一个唯一的传输层协议。

ServerCreator 接口 添加 AfterCommonConfServer 方法
2022-12-03 23:51:51 +08:00

105 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
Package socks5http provides listening both socks5 and http at one port.
This package imports proxy/socks5 and proxy/http package.
# Naming
socks5http 与 clash的 "mixed" 等价。之所以不用 "mixed"这个名称,是因为这容易在本作中引起歧义。
clash是一个客户端它没有服务端所以它的监听只是用于内网监听所以监听协议 只有http和socks5 两种,所以 它 叫 "mixed" 是没有歧义的;
而本作与v2ray一样是支持多种服务端协议的如果也叫 mixed 的话,会让人误以为,这是一个 "万能协议", 啥都能监听, 而这显然是误区。 命名为 socks5http, 则清晰地指出了 该协议的功能。
# Password
为了避免混淆,本包不支持密码验证。你要是有这么高的密码要求 那你不妨用单独的协议,而不要用混合版。
实际上本包就是先经过http然后如果不是http代理请求就会回落到socks5.
所以你可以通过 设计回落的方式来达到 有密码 的 混合端口 的需求。
*/
package socks5http
import (
"io"
"net"
"net/url"
"github.com/e1732a364fed/v2ray_simple/proxy/http"
"github.com/e1732a364fed/v2ray_simple/proxy/socks5"
"github.com/e1732a364fed/v2ray_simple/utils"
"github.com/e1732a364fed/v2ray_simple/netLayer"
"github.com/e1732a364fed/v2ray_simple/proxy"
)
const Name = "socks5http"
func init() {
proxy.RegisterServer(Name, &ServerCreator{})
}
type ServerCreator struct{ proxy.CreatorCommonStruct }
// true
func (ServerCreator) MultiTransportLayer() bool {
return true
}
func (ServerCreator) URLToListenConf(u *url.URL, lc *proxy.ListenConf, format int) (*proxy.ListenConf, error) {
if lc == nil {
lc = &proxy.ListenConf{}
}
return lc, nil
}
func (ServerCreator) NewServer(dc *proxy.ListenConf) (proxy.Server, error) {
return newServer(), nil
}
func newServer() *Server {
return &Server{
hs: http.NewServer(),
ss: socks5.NewServer(),
}
}
type Server struct {
proxy.Base
hs *http.Server
ss *socks5.Server
}
func (*Server) Name() string {
return Name
}
func (s *Server) Handshake(underlay net.Conn) (newconn net.Conn, msgConn netLayer.MsgConn, targetAddr netLayer.Addr, err error) {
newconn, _, targetAddr, err = s.hs.Handshake(underlay)
if err == nil {
return
}
if be, ok := err.(utils.ErrBuffer); ok {
buf := be.Buf
//if ce := utils.CanLogDebug("socks5http: http failed, will try socks5"); ce != nil {
// ce.Write(zap.Int("buflen", buf.Len()))
//}
newConn := &netLayer.ReadWrapper{
Conn: underlay,
OptionalReader: io.MultiReader(buf, underlay),
RemainFirstBufLen: buf.Len(),
}
return s.ss.Handshake(newConn)
}
return
}