mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-21 09:36:34 -05:00
allow redirection in dokodemo
This commit is contained in:
parent
666dff02b0
commit
1c06fc216a
@ -5,8 +5,9 @@ import (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Address v2net.Address
|
||||
Port v2net.Port
|
||||
Network *v2net.NetworkList
|
||||
Timeout int
|
||||
FollowRedirect bool
|
||||
Address v2net.Address
|
||||
Port v2net.Port
|
||||
Network *v2net.NetworkList
|
||||
Timeout int
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ func (this *Config) UnmarshalJSON(data []byte) error {
|
||||
PortValue v2net.Port `json:"port"`
|
||||
NetworkList *v2net.NetworkList `json:"network"`
|
||||
TimeoutValue int `json:"timeout"`
|
||||
Redirect bool `json:"followRedirect"`
|
||||
}
|
||||
rawConfig := new(DokodemoConfig)
|
||||
if err := json.Unmarshal(data, rawConfig); err != nil {
|
||||
@ -25,6 +26,7 @@ func (this *Config) UnmarshalJSON(data []byte) error {
|
||||
this.Port = rawConfig.PortValue
|
||||
this.Network = rawConfig.NetworkList
|
||||
this.Timeout = rawConfig.TimeoutValue
|
||||
this.FollowRedirect = rawConfig.Redirect
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package dokodemo
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"github.com/v2ray/v2ray-core/app"
|
||||
"github.com/v2ray/v2ray-core/app/dispatcher"
|
||||
@ -14,6 +15,8 @@ import (
|
||||
"github.com/v2ray/v2ray-core/transport/hub"
|
||||
)
|
||||
|
||||
const SO_ORIGINAL_DST = 80
|
||||
|
||||
type DokodemoDoor struct {
|
||||
tcpMutex sync.RWMutex
|
||||
udpMutex sync.RWMutex
|
||||
@ -129,7 +132,16 @@ func (this *DokodemoDoor) ListenTCP() error {
|
||||
func (this *DokodemoDoor) HandleTCPConnection(conn *hub.Connection) {
|
||||
defer conn.Close()
|
||||
|
||||
ray := this.packetDispatcher.DispatchToOutbound(v2net.TCPDestination(this.address, this.port))
|
||||
dest := v2net.TCPDestination(this.address, this.port)
|
||||
if this.config.FollowRedirect {
|
||||
originalDest := GetOriginalDestination(conn)
|
||||
if originalDest != nil {
|
||||
log.Info("Dokodemo: Following redirect to: ", originalDest)
|
||||
dest = originalDest
|
||||
}
|
||||
}
|
||||
|
||||
ray := this.packetDispatcher.DispatchToOutbound(dest)
|
||||
defer ray.InboundOutput().Release()
|
||||
|
||||
var inputFinish, outputFinish sync.Mutex
|
||||
@ -160,6 +172,23 @@ func (this *DokodemoDoor) HandleTCPConnection(conn *hub.Connection) {
|
||||
inputFinish.Lock()
|
||||
}
|
||||
|
||||
func GetOriginalDestination(conn *hub.Connection) v2net.Destination {
|
||||
fd, err := conn.SysFd()
|
||||
if err != nil {
|
||||
log.Info("Dokodemo: Failed to get original destination: ", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
addr, err := syscall.GetsockoptIPv6Mreq(fd, syscall.IPPROTO_IP, SO_ORIGINAL_DST)
|
||||
if err != nil {
|
||||
log.Info("Dokodemo: Failed to call getsockopt: ", err)
|
||||
return nil
|
||||
}
|
||||
ip := v2net.IPAddress(addr.Multiaddr[4:8])
|
||||
port := uint16(addr.Multiaddr[2])<<8 + uint16(addr.Multiaddr[3])
|
||||
return v2net.TCPDestination(ip, v2net.Port(port))
|
||||
}
|
||||
|
||||
func init() {
|
||||
internal.MustRegisterInboundHandlerCreator("dokodemo-door",
|
||||
func(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||
|
@ -1,12 +1,18 @@
|
||||
package hub
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/v2ray/v2ray-core/transport"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidConn = errors.New("Invalid Connection.")
|
||||
)
|
||||
|
||||
type ConnectionHandler func(*Connection)
|
||||
|
||||
type ConnectionManager interface {
|
||||
@ -73,3 +79,17 @@ func (this *Connection) SetReusable(reusable bool) {
|
||||
func (this *Connection) Reusable() bool {
|
||||
return this.reusable
|
||||
}
|
||||
|
||||
func (this *Connection) SysFd() (int, error) {
|
||||
cv := reflect.ValueOf(this.conn)
|
||||
switch ce := cv.Elem(); ce.Kind() {
|
||||
case reflect.Struct:
|
||||
netfd := ce.FieldByName("conn").FieldByName("fd")
|
||||
switch fe := netfd.Elem(); fe.Kind() {
|
||||
case reflect.Struct:
|
||||
fd := fe.FieldByName("sysfd")
|
||||
return int(fd.Int()), nil
|
||||
}
|
||||
}
|
||||
return 0, ErrInvalidConn
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user