Files
v2ray_simple/proxy/reject.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

162 lines
4.1 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 proxy
import (
"io"
"net"
"net/url"
"github.com/e1732a364fed/v2ray_simple/httpLayer"
"github.com/e1732a364fed/v2ray_simple/netLayer"
"github.com/e1732a364fed/v2ray_simple/utils"
"go.uber.org/zap"
)
const RejectName = "reject"
func tryRejectWithHttpRespAndClose(rejectType string, underlay net.Conn) {
switch rejectType {
default:
if ce := utils.CanLogDebug("reject server got unimplemented rejectType. Use default response instead."); ce != nil {
ce.Write(
zap.String("type", rejectType),
)
}
fallthrough
case "http":
underlay.Write([]byte(httpLayer.Err403response))
case "nginx":
SetCommonReadTimeout(underlay)
bs := utils.GetPacket()
defer utils.PutPacket(bs)
n, err := underlay.Read(bs)
if err == nil && n > 0 {
bs = bs[:n]
_, _, _, _, failreason := httpLayer.ParseH1Request(bs, false)
if failreason == 0 {
underlay.Write([]byte(httpLayer.GetNginx403Response())) //forbiden
} else {
underlay.Write([]byte(httpLayer.GetNginx400Response())) //bad request, for non-http (illegal) request
}
} else {
if ce := utils.CanLogDebug("reject server got Read error"); ce != nil {
ce.Write(
zap.Error(err),
)
}
}
}
underlay.Close() //实测如果不Write 响应就算Close掉客户端的连接也不会真正被关闭
}
// implements ClientCreator and ServerCreator for reject
type RejectCreator struct{ CreatorCommonStruct }
func (RejectCreator) UseUDPAsMsgConn() bool {
return false
}
func (RejectCreator) NewClient(dc *DialConf) (Client, error) {
r := &RejectClient{}
r.initByCommonConf(&dc.CommonConf)
return r, nil
}
func (rc RejectCreator) URLToDialConf(url *url.URL, iv *DialConf, format int) (*DialConf, error) {
if iv == nil {
iv = &DialConf{}
}
return iv, nil
}
func (rc RejectCreator) URLToListenConf(url *url.URL, iv *ListenConf, format int) (*ListenConf, error) {
if iv == nil {
iv = &ListenConf{}
}
return iv, nil
}
func (RejectCreator) NewServer(lc *ListenConf) (Server, error) {
r := &RejectServer{}
r.initByCommonConf(&lc.CommonConf)
return r, nil
}
type rejectCommon struct {
Base
theType string //拒绝响应的类型, 可为空、http或nginx
}
func (*rejectCommon) Name() string { return RejectName }
func (rc *rejectCommon) initByCommonConf(cc *CommonConf) {
if cc.Extra != nil {
if thing := cc.Extra["type"]; thing != nil {
if t, ok := thing.(string); ok && t != "" {
rc.theType = t
}
}
}
}
/*
RejectClient implements Client, optionally response a 403 and close the underlay immediately.
v2ray的 "blackhole" 名字不准确, 本作 使用 "reject".
正常的 blackhole并不会立即关闭连接而是悄无声息地 读 数据,并舍弃。
而 v2ray的 blackhole是 选择性返回 403错误 后立即关闭连接. 完全是 Reject的特性。
而且 理想情况下 应该分析一下请求如果请求是合法的http请求则返回403否则 应该返回 400错误.
所以我们在v2ray的基础上再推出一个 "nginx"类型,来达到上面的分类返回不同错误的效果。
默认为 "" 空类型,直接 close不反回任何信息。 若设为 http则返回一个403错误若设为nginx则分类返回400/403错误。
*/
type RejectClient struct {
rejectCommon
}
func (*RejectClient) GetCreator() ClientCreator {
return RejectCreator{}
}
// optionally response 403 and close the underlay, return io.EOF.
func (c *RejectClient) Handshake(underlay net.Conn, _ []byte, _ netLayer.Addr) (result io.ReadWriteCloser, err error) {
tryRejectWithHttpRespAndClose(c.theType, underlay)
return nil, io.EOF
}
// function the same as Handshake
func (c *RejectClient) EstablishUDPChannel(underlay net.Conn, _ []byte, _ netLayer.Addr) (netLayer.MsgConn, error) {
tryRejectWithHttpRespAndClose(c.theType, underlay)
return nil, io.EOF
}
// mimic the behavior of RejectClient
type RejectServer struct {
rejectCommon
}
// return utils.ErrHandled
func (s *RejectServer) Handshake(underlay net.Conn) (_ net.Conn, _ netLayer.MsgConn, _ netLayer.Addr, e error) {
tryRejectWithHttpRespAndClose(s.theType, underlay)
e = utils.ErrHandled
return
}