mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-22 01:57:12 -05:00
allow redirection in dokodemo
This commit is contained in:
parent
666dff02b0
commit
1c06fc216a
@ -5,6 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
FollowRedirect bool
|
||||||
Address v2net.Address
|
Address v2net.Address
|
||||||
Port v2net.Port
|
Port v2net.Port
|
||||||
Network *v2net.NetworkList
|
Network *v2net.NetworkList
|
||||||
|
@ -16,6 +16,7 @@ func (this *Config) UnmarshalJSON(data []byte) error {
|
|||||||
PortValue v2net.Port `json:"port"`
|
PortValue v2net.Port `json:"port"`
|
||||||
NetworkList *v2net.NetworkList `json:"network"`
|
NetworkList *v2net.NetworkList `json:"network"`
|
||||||
TimeoutValue int `json:"timeout"`
|
TimeoutValue int `json:"timeout"`
|
||||||
|
Redirect bool `json:"followRedirect"`
|
||||||
}
|
}
|
||||||
rawConfig := new(DokodemoConfig)
|
rawConfig := new(DokodemoConfig)
|
||||||
if err := json.Unmarshal(data, rawConfig); err != nil {
|
if err := json.Unmarshal(data, rawConfig); err != nil {
|
||||||
@ -25,6 +26,7 @@ func (this *Config) UnmarshalJSON(data []byte) error {
|
|||||||
this.Port = rawConfig.PortValue
|
this.Port = rawConfig.PortValue
|
||||||
this.Network = rawConfig.NetworkList
|
this.Network = rawConfig.NetworkList
|
||||||
this.Timeout = rawConfig.TimeoutValue
|
this.Timeout = rawConfig.TimeoutValue
|
||||||
|
this.FollowRedirect = rawConfig.Redirect
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package dokodemo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core/app"
|
"github.com/v2ray/v2ray-core/app"
|
||||||
"github.com/v2ray/v2ray-core/app/dispatcher"
|
"github.com/v2ray/v2ray-core/app/dispatcher"
|
||||||
@ -14,6 +15,8 @@ import (
|
|||||||
"github.com/v2ray/v2ray-core/transport/hub"
|
"github.com/v2ray/v2ray-core/transport/hub"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const SO_ORIGINAL_DST = 80
|
||||||
|
|
||||||
type DokodemoDoor struct {
|
type DokodemoDoor struct {
|
||||||
tcpMutex sync.RWMutex
|
tcpMutex sync.RWMutex
|
||||||
udpMutex sync.RWMutex
|
udpMutex sync.RWMutex
|
||||||
@ -129,7 +132,16 @@ func (this *DokodemoDoor) ListenTCP() error {
|
|||||||
func (this *DokodemoDoor) HandleTCPConnection(conn *hub.Connection) {
|
func (this *DokodemoDoor) HandleTCPConnection(conn *hub.Connection) {
|
||||||
defer conn.Close()
|
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()
|
defer ray.InboundOutput().Release()
|
||||||
|
|
||||||
var inputFinish, outputFinish sync.Mutex
|
var inputFinish, outputFinish sync.Mutex
|
||||||
@ -160,6 +172,23 @@ func (this *DokodemoDoor) HandleTCPConnection(conn *hub.Connection) {
|
|||||||
inputFinish.Lock()
|
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() {
|
func init() {
|
||||||
internal.MustRegisterInboundHandlerCreator("dokodemo-door",
|
internal.MustRegisterInboundHandlerCreator("dokodemo-door",
|
||||||
func(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
func(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
package hub
|
package hub
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core/transport"
|
"github.com/v2ray/v2ray-core/transport"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrInvalidConn = errors.New("Invalid Connection.")
|
||||||
|
)
|
||||||
|
|
||||||
type ConnectionHandler func(*Connection)
|
type ConnectionHandler func(*Connection)
|
||||||
|
|
||||||
type ConnectionManager interface {
|
type ConnectionManager interface {
|
||||||
@ -73,3 +79,17 @@ func (this *Connection) SetReusable(reusable bool) {
|
|||||||
func (this *Connection) Reusable() bool {
|
func (this *Connection) Reusable() bool {
|
||||||
return this.reusable
|
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