mirror of
https://github.com/v2fly/v2ray-core.git
synced 2025-02-20 23:47:21 -05:00
Merge branch 'master' into websockwt
This commit is contained in:
commit
7259b3363b
@ -2,12 +2,10 @@ language: go
|
|||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.6.3
|
- 1.6.3
|
||||||
|
|
||||||
before_install:
|
|
||||||
- go get golang.org/x/tools/cmd/cover
|
|
||||||
- go get github.com/onsi/gomega
|
|
||||||
- go get github.com/onsi/ginkgo
|
|
||||||
|
|
||||||
|
git:
|
||||||
|
depth: 5
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- go test -tags json github.com/v2ray/v2ray-core/...
|
- go test -tags json github.com/v2ray/v2ray-core/...
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ package dispatcher
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/v2ray/v2ray-core/app"
|
"github.com/v2ray/v2ray-core/app"
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
"github.com/v2ray/v2ray-core/proxy"
|
||||||
"github.com/v2ray/v2ray-core/transport/ray"
|
"github.com/v2ray/v2ray-core/transport/ray"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -12,5 +12,5 @@ const (
|
|||||||
|
|
||||||
// PacketDispatcher dispatch a packet and possibly further network payload to its destination.
|
// PacketDispatcher dispatch a packet and possibly further network payload to its destination.
|
||||||
type PacketDispatcher interface {
|
type PacketDispatcher interface {
|
||||||
DispatchToOutbound(destination v2net.Destination) ray.InboundRay
|
DispatchToOutbound(meta *proxy.InboundHandlerMeta, session *proxy.SessionInfo) ray.InboundRay
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"github.com/v2ray/v2ray-core/app"
|
"github.com/v2ray/v2ray-core/app"
|
||||||
"github.com/v2ray/v2ray-core/app/proxyman"
|
"github.com/v2ray/v2ray-core/app/proxyman"
|
||||||
"github.com/v2ray/v2ray-core/app/router"
|
"github.com/v2ray/v2ray-core/app/router"
|
||||||
|
"github.com/v2ray/v2ray-core/common/alloc"
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
"github.com/v2ray/v2ray-core/proxy"
|
"github.com/v2ray/v2ray-core/proxy"
|
||||||
@ -42,9 +43,10 @@ func (this *DefaultDispatcher) Release() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DefaultDispatcher) DispatchToOutbound(destination v2net.Destination) ray.InboundRay {
|
func (this *DefaultDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta, session *proxy.SessionInfo) ray.InboundRay {
|
||||||
direct := ray.NewRay()
|
direct := ray.NewRay()
|
||||||
dispatcher := this.ohm.GetDefaultHandler()
|
dispatcher := this.ohm.GetDefaultHandler()
|
||||||
|
destination := session.Destination
|
||||||
|
|
||||||
if this.router != nil {
|
if this.router != nil {
|
||||||
if tag, err := this.router.TakeDetour(destination); err == nil {
|
if tag, err := this.router.TakeDetour(destination); err == nil {
|
||||||
@ -59,7 +61,11 @@ func (this *DefaultDispatcher) DispatchToOutbound(destination v2net.Destination)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go this.FilterPacketAndDispatch(destination, direct, dispatcher)
|
if meta.AllowPassiveConnection {
|
||||||
|
go dispatcher.Dispatch(destination, alloc.NewLocalBuffer(32).Clear(), direct)
|
||||||
|
} else {
|
||||||
|
go this.FilterPacketAndDispatch(destination, direct, dispatcher)
|
||||||
|
}
|
||||||
|
|
||||||
return direct
|
return direct
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package testing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
|
"github.com/v2ray/v2ray-core/proxy"
|
||||||
"github.com/v2ray/v2ray-core/transport/ray"
|
"github.com/v2ray/v2ray-core/transport/ray"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -29,10 +30,10 @@ func NewTestPacketDispatcher(handler func(destination v2net.Destination, traffic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TestPacketDispatcher) DispatchToOutbound(destination v2net.Destination) ray.InboundRay {
|
func (this *TestPacketDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta, session *proxy.SessionInfo) ray.InboundRay {
|
||||||
traffic := ray.NewRay()
|
traffic := ray.NewRay()
|
||||||
this.Destination <- destination
|
this.Destination <- session.Destination
|
||||||
go this.Handler(destination, traffic)
|
go this.Handler(session.Destination, traffic)
|
||||||
|
|
||||||
return traffic
|
return traffic
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ func (this *Config) UnmarshalJSON(data []byte) error {
|
|||||||
if jsonConfig.Hosts != nil {
|
if jsonConfig.Hosts != nil {
|
||||||
this.Hosts = make(map[string]net.IP)
|
this.Hosts = make(map[string]net.IP)
|
||||||
for domain, ip := range jsonConfig.Hosts {
|
for domain, ip := range jsonConfig.Hosts {
|
||||||
if ip.Address.IsDomain() {
|
if ip.Address.Family().IsDomain() {
|
||||||
return errors.New(ip.Address.String() + " is not an IP.")
|
return errors.New(ip.Address.String() + " is not an IP.")
|
||||||
}
|
}
|
||||||
this.Hosts[domain] = ip.Address.IP()
|
this.Hosts[domain] = ip.Address.IP()
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/v2ray/v2ray-core/common/dice"
|
"github.com/v2ray/v2ray-core/common/dice"
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
|
"github.com/v2ray/v2ray-core/proxy"
|
||||||
"github.com/v2ray/v2ray-core/transport/internet/udp"
|
"github.com/v2ray/v2ray-core/transport/internet/udp"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
@ -49,9 +50,11 @@ type UDPNameServer struct {
|
|||||||
|
|
||||||
func NewUDPNameServer(address v2net.Destination, dispatcher dispatcher.PacketDispatcher) *UDPNameServer {
|
func NewUDPNameServer(address v2net.Destination, dispatcher dispatcher.PacketDispatcher) *UDPNameServer {
|
||||||
s := &UDPNameServer{
|
s := &UDPNameServer{
|
||||||
address: address,
|
address: address,
|
||||||
requests: make(map[uint16]*PendingRequest),
|
requests: make(map[uint16]*PendingRequest),
|
||||||
udpServer: udp.NewUDPServer(dispatcher),
|
udpServer: udp.NewUDPServer(&proxy.InboundHandlerMeta{
|
||||||
|
AllowPassiveConnection: false,
|
||||||
|
}, dispatcher),
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
@ -162,7 +165,7 @@ func (this *UDPNameServer) BuildQueryA(domain string, id uint16) *alloc.Buffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *UDPNameServer) DispatchQuery(payload *alloc.Buffer) {
|
func (this *UDPNameServer) DispatchQuery(payload *alloc.Buffer) {
|
||||||
this.udpServer.Dispatch(pseudoDestination, this.address, payload, this.HandleResponse)
|
this.udpServer.Dispatch(&proxy.SessionInfo{Source: pseudoDestination, Destination: this.address}, payload, this.HandleResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *UDPNameServer) QueryA(domain string) <-chan *ARecord {
|
func (this *UDPNameServer) QueryA(domain string) <-chan *ARecord {
|
||||||
|
@ -42,7 +42,7 @@ func NewCacheServer(space app.Space, config *Config) *CacheServer {
|
|||||||
|
|
||||||
dispatcher := space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)
|
dispatcher := space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher)
|
||||||
for idx, ns := range config.NameServers {
|
for idx, ns := range config.NameServers {
|
||||||
if ns.Address().IsDomain() && ns.Address().Domain() == "localhost" {
|
if ns.Address().Family().IsDomain() && ns.Address().Domain() == "localhost" {
|
||||||
server.servers[idx] = &LocalNameServer{}
|
server.servers[idx] = &LocalNameServer{}
|
||||||
} else {
|
} else {
|
||||||
server.servers[idx] = NewUDPNameServer(ns, dispatcher)
|
server.servers[idx] = NewUDPNameServer(ns, dispatcher)
|
||||||
|
@ -73,7 +73,7 @@ func NewPlainDomainMatcher(pattern string) *PlainDomainMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *PlainDomainMatcher) Apply(dest v2net.Destination) bool {
|
func (this *PlainDomainMatcher) Apply(dest v2net.Destination) bool {
|
||||||
if !dest.Address().IsDomain() {
|
if !dest.Address().Family().IsDomain() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
domain := dest.Address().Domain()
|
domain := dest.Address().Domain()
|
||||||
@ -95,7 +95,7 @@ func NewRegexpDomainMatcher(pattern string) (*RegexpDomainMatcher, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *RegexpDomainMatcher) Apply(dest v2net.Destination) bool {
|
func (this *RegexpDomainMatcher) Apply(dest v2net.Destination) bool {
|
||||||
if !dest.Address().IsDomain() {
|
if !dest.Address().Family().IsDomain() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
domain := dest.Address().Domain()
|
domain := dest.Address().Domain()
|
||||||
@ -117,7 +117,7 @@ func NewCIDRMatcher(ipnet string) (*CIDRMatcher, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *CIDRMatcher) Apply(dest v2net.Destination) bool {
|
func (this *CIDRMatcher) Apply(dest v2net.Destination) bool {
|
||||||
if !dest.Address().IsIPv4() && !dest.Address().IsIPv6() {
|
if !dest.Address().Family().Either(v2net.AddressFamilyIPv4, v2net.AddressFamilyIPv6) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return this.cidr.Contains(dest.Address().IP())
|
return this.cidr.Contains(dest.Address().IP())
|
||||||
@ -134,7 +134,7 @@ func NewIPv4Matcher(ipnet *v2net.IPNet) *IPv4Matcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *IPv4Matcher) Apply(dest v2net.Destination) bool {
|
func (this *IPv4Matcher) Apply(dest v2net.Destination) bool {
|
||||||
if !dest.Address().IsIPv4() {
|
if !dest.Address().Family().Either(v2net.AddressFamilyIPv4) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return this.ipv4net.Contains(dest.Address().IP())
|
return this.ipv4net.Contains(dest.Address().IP())
|
||||||
|
@ -64,7 +64,7 @@ func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, erro
|
|||||||
return rule.Tag, nil
|
return rule.Tag, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if this.config.DomainStrategy == UseIPIfNonMatch && dest.Address().IsDomain() {
|
if this.config.DomainStrategy == UseIPIfNonMatch && dest.Address().Family().IsDomain() {
|
||||||
log.Info("Router: Looking up IP for ", dest)
|
log.Info("Router: Looking up IP for ", dest)
|
||||||
ipDests := this.ResolveIP(dest)
|
ipDests := this.ResolveIP(dest)
|
||||||
if ipDests != nil {
|
if ipDests != nil {
|
||||||
|
@ -12,15 +12,41 @@ var (
|
|||||||
AnyIP = IPAddress([]byte{0, 0, 0, 0})
|
AnyIP = IPAddress([]byte{0, 0, 0, 0})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type AddressFamily int
|
||||||
|
|
||||||
|
const (
|
||||||
|
AddressFamilyIPv4 = AddressFamily(0)
|
||||||
|
AddressFamilyIPv6 = AddressFamily(1)
|
||||||
|
AddressFamilyDomain = AddressFamily(2)
|
||||||
|
)
|
||||||
|
|
||||||
|
func (this AddressFamily) Either(fs ...AddressFamily) bool {
|
||||||
|
for _, f := range fs {
|
||||||
|
if this == f {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this AddressFamily) IsIPv4() bool {
|
||||||
|
return this == AddressFamilyIPv4
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this AddressFamily) IsIPv6() bool {
|
||||||
|
return this == AddressFamilyIPv6
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this AddressFamily) IsDomain() bool {
|
||||||
|
return this == AddressFamilyDomain
|
||||||
|
}
|
||||||
|
|
||||||
// Address represents a network address to be communicated with. It may be an IP address or domain
|
// Address represents a network address to be communicated with. It may be an IP address or domain
|
||||||
// address, not both. This interface doesn't resolve IP address for a given domain.
|
// address, not both. This interface doesn't resolve IP address for a given domain.
|
||||||
type Address interface {
|
type Address interface {
|
||||||
IP() net.IP // IP of this Address
|
IP() net.IP // IP of this Address
|
||||||
Domain() string // Domain of this Address
|
Domain() string // Domain of this Address
|
||||||
|
Family() AddressFamily
|
||||||
IsIPv4() bool // True if this Address is an IPv4 address
|
|
||||||
IsIPv6() bool // True if this Address is an IPv6 address
|
|
||||||
IsDomain() bool // True if this Address is an domain address
|
|
||||||
|
|
||||||
String() string // String representation of this Address
|
String() string // String representation of this Address
|
||||||
Equals(Address) bool
|
Equals(Address) bool
|
||||||
@ -75,16 +101,8 @@ func (addr *ipv4Address) Domain() string {
|
|||||||
panic("Calling Domain() on an IPv4Address.")
|
panic("Calling Domain() on an IPv4Address.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (addr *ipv4Address) IsIPv4() bool {
|
func (addr *ipv4Address) Family() AddressFamily {
|
||||||
return true
|
return AddressFamilyIPv4
|
||||||
}
|
|
||||||
|
|
||||||
func (addr *ipv4Address) IsIPv6() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (addr *ipv4Address) IsDomain() bool {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ipv4Address) String() string {
|
func (this *ipv4Address) String() string {
|
||||||
@ -112,16 +130,8 @@ func (addr *ipv6Address) Domain() string {
|
|||||||
panic("Calling Domain() on an IPv6Address.")
|
panic("Calling Domain() on an IPv6Address.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (addr *ipv6Address) IsIPv4() bool {
|
func (this *ipv6Address) Family() AddressFamily {
|
||||||
return false
|
return AddressFamilyIPv6
|
||||||
}
|
|
||||||
|
|
||||||
func (addr *ipv6Address) IsIPv6() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (addr *ipv6Address) IsDomain() bool {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ipv6Address) String() string {
|
func (this *ipv6Address) String() string {
|
||||||
@ -161,16 +171,8 @@ func (addr *domainAddress) Domain() string {
|
|||||||
return string(*addr)
|
return string(*addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (addr *domainAddress) IsIPv4() bool {
|
func (addr *domainAddress) Family() AddressFamily {
|
||||||
return false
|
return AddressFamilyDomain
|
||||||
}
|
|
||||||
|
|
||||||
func (addr *domainAddress) IsIPv6() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (addr *domainAddress) IsDomain() bool {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *domainAddress) String() string {
|
func (this *domainAddress) String() string {
|
||||||
|
@ -18,8 +18,8 @@ func TestIPParsing(t *testing.T) {
|
|||||||
var address AddressJson
|
var address AddressJson
|
||||||
err := json.Unmarshal([]byte(rawJson), &address)
|
err := json.Unmarshal([]byte(rawJson), &address)
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
assert.Bool(address.Address.IsIPv4()).IsTrue()
|
assert.Bool(address.Address.Family().Either(AddressFamilyIPv4)).IsTrue()
|
||||||
assert.Bool(address.Address.IsDomain()).IsFalse()
|
assert.Bool(address.Address.Family().Either(AddressFamilyDomain)).IsFalse()
|
||||||
assert.Bool(address.Address.IP().Equal(net.ParseIP("8.8.8.8"))).IsTrue()
|
assert.Bool(address.Address.IP().Equal(net.ParseIP("8.8.8.8"))).IsTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,8 +30,8 @@ func TestDomainParsing(t *testing.T) {
|
|||||||
var address AddressJson
|
var address AddressJson
|
||||||
err := json.Unmarshal([]byte(rawJson), &address)
|
err := json.Unmarshal([]byte(rawJson), &address)
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
assert.Bool(address.Address.IsIPv4()).IsFalse()
|
assert.Bool(address.Address.Family().Either(AddressFamilyIPv4)).IsFalse()
|
||||||
assert.Bool(address.Address.IsDomain()).IsTrue()
|
assert.Bool(address.Address.Family().Either(AddressFamilyDomain)).IsTrue()
|
||||||
assert.String(address.Address.Domain()).Equals("v2ray.com")
|
assert.String(address.Address.Domain()).Equals("v2ray.com")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
package net
|
package net
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
// Destination represents a network destination including address and protocol (tcp / udp).
|
// Destination represents a network destination including address and protocol (tcp / udp).
|
||||||
type Destination interface {
|
type Destination interface {
|
||||||
Network() Network // Protocol of communication (tcp / udp)
|
Network() Network // Protocol of communication (tcp / udp)
|
||||||
@ -13,6 +17,17 @@ type Destination interface {
|
|||||||
IsUDP() bool // True if destination is reachable via UDP
|
IsUDP() bool // True if destination is reachable via UDP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DestinationFromAddr(addr net.Addr) Destination {
|
||||||
|
switch addr := addr.(type) {
|
||||||
|
case *net.TCPAddr:
|
||||||
|
return TCPDestination(IPAddress(addr.IP), Port(addr.Port))
|
||||||
|
case *net.UDPAddr:
|
||||||
|
return UDPDestination(IPAddress(addr.IP), Port(addr.Port))
|
||||||
|
default:
|
||||||
|
panic("Unknown address type.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TCPDestination creates a TCP destination with given address
|
// TCPDestination creates a TCP destination with given address
|
||||||
func TCPDestination(address Address, port Port) Destination {
|
func TCPDestination(address Address, port Port) Destination {
|
||||||
return &tcpDestination{address: address, port: port}
|
return &tcpDestination{address: address, port: port}
|
||||||
|
2
core.go
2
core.go
@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
version = "1.24"
|
version = "1.25"
|
||||||
build = "Custom"
|
build = "Custom"
|
||||||
codename = "New Order"
|
codename = "New Order"
|
||||||
intro = "An unified platform for anti-censorship."
|
intro = "An unified platform for anti-censorship."
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// +build json
|
||||||
|
|
||||||
package blackhole_test
|
package blackhole_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -89,7 +89,7 @@ func (this *DokodemoDoor) Start() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *DokodemoDoor) ListenUDP() error {
|
func (this *DokodemoDoor) ListenUDP() error {
|
||||||
this.udpServer = udp.NewUDPServer(this.packetDispatcher)
|
this.udpServer = udp.NewUDPServer(this.meta, this.packetDispatcher)
|
||||||
udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, this.handleUDPPackets)
|
udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, this.handleUDPPackets)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Dokodemo failed to listen on ", this.meta.Address, ":", this.meta.Port, ": ", err)
|
log.Error("Dokodemo failed to listen on ", this.meta.Address, ":", this.meta.Port, ": ", err)
|
||||||
@ -102,7 +102,8 @@ func (this *DokodemoDoor) ListenUDP() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, dest v2net.Destination) {
|
func (this *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, dest v2net.Destination) {
|
||||||
this.udpServer.Dispatch(dest, v2net.UDPDestination(this.address, this.port), payload, this.handleUDPResponse)
|
this.udpServer.Dispatch(
|
||||||
|
&proxy.SessionInfo{Source: dest, Destination: v2net.UDPDestination(this.address, this.port)}, payload, this.handleUDPResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DokodemoDoor) handleUDPResponse(dest v2net.Destination, payload *alloc.Buffer) {
|
func (this *DokodemoDoor) handleUDPResponse(dest v2net.Destination, payload *alloc.Buffer) {
|
||||||
@ -148,7 +149,10 @@ func (this *DokodemoDoor) HandleTCPConnection(conn internet.Connection) {
|
|||||||
}
|
}
|
||||||
log.Info("Dokodemo: Handling request to ", dest)
|
log.Info("Dokodemo: Handling request to ", dest)
|
||||||
|
|
||||||
ray := this.packetDispatcher.DispatchToOutbound(dest)
|
ray := this.packetDispatcher.DispatchToOutbound(this.meta, &proxy.SessionInfo{
|
||||||
|
Source: v2net.DestinationFromAddr(conn.RemoteAddr()),
|
||||||
|
Destination: dest,
|
||||||
|
})
|
||||||
defer ray.InboundOutput().Release()
|
defer ray.InboundOutput().Release()
|
||||||
|
|
||||||
var inputFinish, outputFinish sync.Mutex
|
var inputFinish, outputFinish sync.Mutex
|
||||||
|
@ -47,7 +47,7 @@ func NewFreedomConnection(config *Config, space app.Space, meta *proxy.OutboundH
|
|||||||
|
|
||||||
// @Private
|
// @Private
|
||||||
func (this *FreedomConnection) ResolveIP(destination v2net.Destination) v2net.Destination {
|
func (this *FreedomConnection) ResolveIP(destination v2net.Destination) v2net.Destination {
|
||||||
if !destination.Address().IsDomain() {
|
if !destination.Address().Family().IsDomain() {
|
||||||
return destination
|
return destination
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ func (this *FreedomConnection) Dispatch(destination v2net.Destination, payload *
|
|||||||
defer ray.OutboundOutput().Close()
|
defer ray.OutboundOutput().Close()
|
||||||
|
|
||||||
var conn internet.Connection
|
var conn internet.Connection
|
||||||
if this.domainStrategy == DomainStrategyUseIP && destination.Address().IsDomain() {
|
if this.domainStrategy == DomainStrategyUseIP && destination.Address().Family().IsDomain() {
|
||||||
destination = this.ResolveIP(destination)
|
destination = this.ResolveIP(destination)
|
||||||
}
|
}
|
||||||
err := retry.Timed(5, 100).On(func() error {
|
err := retry.Timed(5, 100).On(func() error {
|
||||||
|
@ -119,14 +119,18 @@ func (this *Server) handleConnection(conn internet.Connection) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Access(conn.RemoteAddr(), request.URL, log.AccessAccepted, "")
|
log.Access(conn.RemoteAddr(), request.URL, log.AccessAccepted, "")
|
||||||
|
session := &proxy.SessionInfo{
|
||||||
|
Source: v2net.DestinationFromAddr(conn.RemoteAddr()),
|
||||||
|
Destination: dest,
|
||||||
|
}
|
||||||
if strings.ToUpper(request.Method) == "CONNECT" {
|
if strings.ToUpper(request.Method) == "CONNECT" {
|
||||||
this.handleConnect(request, dest, reader, conn)
|
this.handleConnect(request, session, reader, conn)
|
||||||
} else {
|
} else {
|
||||||
this.handlePlainHTTP(request, dest, reader, conn)
|
this.handlePlainHTTP(request, session, reader, conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) handleConnect(request *http.Request, destination v2net.Destination, reader io.Reader, writer io.Writer) {
|
func (this *Server) handleConnect(request *http.Request, session *proxy.SessionInfo, reader io.Reader, writer io.Writer) {
|
||||||
response := &http.Response{
|
response := &http.Response{
|
||||||
Status: "200 OK",
|
Status: "200 OK",
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
@ -140,7 +144,7 @@ func (this *Server) handleConnect(request *http.Request, destination v2net.Desti
|
|||||||
}
|
}
|
||||||
response.Write(writer)
|
response.Write(writer)
|
||||||
|
|
||||||
ray := this.packetDispatcher.DispatchToOutbound(destination)
|
ray := this.packetDispatcher.DispatchToOutbound(this.meta, session)
|
||||||
this.transport(reader, writer, ray)
|
this.transport(reader, writer, ray)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,7 +213,7 @@ func (this *Server) GenerateResponse(statusCode int, status string) *http.Respon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) handlePlainHTTP(request *http.Request, dest v2net.Destination, reader *bufio.Reader, writer io.Writer) {
|
func (this *Server) handlePlainHTTP(request *http.Request, session *proxy.SessionInfo, reader *bufio.Reader, writer io.Writer) {
|
||||||
if len(request.URL.Host) <= 0 {
|
if len(request.URL.Host) <= 0 {
|
||||||
response := this.GenerateResponse(400, "Bad Request")
|
response := this.GenerateResponse(400, "Bad Request")
|
||||||
response.Write(writer)
|
response.Write(writer)
|
||||||
@ -220,7 +224,7 @@ func (this *Server) handlePlainHTTP(request *http.Request, dest v2net.Destinatio
|
|||||||
request.Host = request.URL.Host
|
request.Host = request.URL.Host
|
||||||
StripHopByHopHeaders(request)
|
StripHopByHopHeaders(request)
|
||||||
|
|
||||||
ray := this.packetDispatcher.DispatchToOutbound(dest)
|
ray := this.packetDispatcher.DispatchToOutbound(this.meta, session)
|
||||||
defer ray.InboundInput().Close()
|
defer ray.InboundInput().Close()
|
||||||
defer ray.InboundOutput().Release()
|
defer ray.InboundOutput().Release()
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ package proxy // import "github.com/v2ray/v2ray-core/proxy"
|
|||||||
import (
|
import (
|
||||||
"github.com/v2ray/v2ray-core/common/alloc"
|
"github.com/v2ray/v2ray-core/common/alloc"
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
|
"github.com/v2ray/v2ray-core/common/protocol"
|
||||||
"github.com/v2ray/v2ray-core/transport/internet"
|
"github.com/v2ray/v2ray-core/transport/internet"
|
||||||
"github.com/v2ray/v2ray-core/transport/ray"
|
"github.com/v2ray/v2ray-core/transport/ray"
|
||||||
)
|
)
|
||||||
@ -15,11 +16,18 @@ const (
|
|||||||
HandlerStateRunning = HandlerState(1)
|
HandlerStateRunning = HandlerState(1)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type SessionInfo struct {
|
||||||
|
Source v2net.Destination
|
||||||
|
Destination v2net.Destination
|
||||||
|
User *protocol.User
|
||||||
|
}
|
||||||
|
|
||||||
type InboundHandlerMeta struct {
|
type InboundHandlerMeta struct {
|
||||||
Tag string
|
Tag string
|
||||||
Address v2net.Address
|
Address v2net.Address
|
||||||
Port v2net.Port
|
Port v2net.Port
|
||||||
StreamSettings *internet.StreamSettings
|
AllowPassiveConnection bool
|
||||||
|
StreamSettings *internet.StreamSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
type OutboundHandlerMeta struct {
|
type OutboundHandlerMeta struct {
|
||||||
|
@ -70,7 +70,7 @@ func (this *Server) Start() error {
|
|||||||
this.tcpHub = tcpHub
|
this.tcpHub = tcpHub
|
||||||
|
|
||||||
if this.config.UDP {
|
if this.config.UDP {
|
||||||
this.udpServer = udp.NewUDPServer(this.packetDispatcher)
|
this.udpServer = udp.NewUDPServer(this.meta, this.packetDispatcher)
|
||||||
udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, this.handlerUDPPayload)
|
udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, this.handlerUDPPayload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Shadowsocks: Failed to listen UDP on ", this.meta.Address, ":", this.meta.Port, ": ", err)
|
log.Error("Shadowsocks: Failed to listen UDP on ", this.meta.Address, ":", this.meta.Port, ": ", err)
|
||||||
@ -114,7 +114,7 @@ func (this *Server) handlerUDPPayload(payload *alloc.Buffer, source v2net.Destin
|
|||||||
log.Access(source, dest, log.AccessAccepted, "")
|
log.Access(source, dest, log.AccessAccepted, "")
|
||||||
log.Info("Shadowsocks: Tunnelling request to ", dest)
|
log.Info("Shadowsocks: Tunnelling request to ", dest)
|
||||||
|
|
||||||
this.udpServer.Dispatch(source, dest, request.DetachUDPPayload(), func(destination v2net.Destination, payload *alloc.Buffer) {
|
this.udpServer.Dispatch(&proxy.SessionInfo{Source: source, Destination: dest}, request.DetachUDPPayload(), func(destination v2net.Destination, payload *alloc.Buffer) {
|
||||||
defer payload.Release()
|
defer payload.Release()
|
||||||
|
|
||||||
response := alloc.NewBuffer().Slice(0, ivLen)
|
response := alloc.NewBuffer().Slice(0, ivLen)
|
||||||
@ -131,14 +131,14 @@ func (this *Server) handlerUDPPayload(payload *alloc.Buffer, source v2net.Destin
|
|||||||
|
|
||||||
writer := crypto.NewCryptionWriter(stream, response)
|
writer := crypto.NewCryptionWriter(stream, response)
|
||||||
|
|
||||||
switch {
|
switch request.Address.Family() {
|
||||||
case request.Address.IsIPv4():
|
case v2net.AddressFamilyIPv4:
|
||||||
writer.Write([]byte{AddrTypeIPv4})
|
writer.Write([]byte{AddrTypeIPv4})
|
||||||
writer.Write(request.Address.IP())
|
writer.Write(request.Address.IP())
|
||||||
case request.Address.IsIPv6():
|
case v2net.AddressFamilyIPv6:
|
||||||
writer.Write([]byte{AddrTypeIPv6})
|
writer.Write([]byte{AddrTypeIPv6})
|
||||||
writer.Write(request.Address.IP())
|
writer.Write(request.Address.IP())
|
||||||
case request.Address.IsDomain():
|
case v2net.AddressFamilyDomain:
|
||||||
writer.Write([]byte{AddrTypeDomain, byte(len(request.Address.Domain()))})
|
writer.Write([]byte{AddrTypeDomain, byte(len(request.Address.Domain()))})
|
||||||
writer.Write([]byte(request.Address.Domain()))
|
writer.Write([]byte(request.Address.Domain()))
|
||||||
}
|
}
|
||||||
@ -204,7 +204,10 @@ func (this *Server) handleConnection(conn internet.Connection) {
|
|||||||
log.Access(conn.RemoteAddr(), dest, log.AccessAccepted, "")
|
log.Access(conn.RemoteAddr(), dest, log.AccessAccepted, "")
|
||||||
log.Info("Shadowsocks: Tunnelling request to ", dest)
|
log.Info("Shadowsocks: Tunnelling request to ", dest)
|
||||||
|
|
||||||
ray := this.packetDispatcher.DispatchToOutbound(dest)
|
ray := this.packetDispatcher.DispatchToOutbound(this.meta, &proxy.SessionInfo{
|
||||||
|
Source: v2net.DestinationFromAddr(conn.RemoteAddr()),
|
||||||
|
Destination: dest,
|
||||||
|
})
|
||||||
defer ray.InboundOutput().Release()
|
defer ray.InboundOutput().Release()
|
||||||
|
|
||||||
var writeFinish sync.Mutex
|
var writeFinish sync.Mutex
|
||||||
|
@ -26,12 +26,12 @@ func (request *Socks5UDPRequest) Destination() v2net.Destination {
|
|||||||
|
|
||||||
func (request *Socks5UDPRequest) Write(buffer *alloc.Buffer) {
|
func (request *Socks5UDPRequest) Write(buffer *alloc.Buffer) {
|
||||||
buffer.AppendBytes(0, 0, request.Fragment)
|
buffer.AppendBytes(0, 0, request.Fragment)
|
||||||
switch {
|
switch request.Address.Family() {
|
||||||
case request.Address.IsIPv4():
|
case v2net.AddressFamilyIPv4:
|
||||||
buffer.AppendBytes(AddrTypeIPv4).Append(request.Address.IP())
|
buffer.AppendBytes(AddrTypeIPv4).Append(request.Address.IP())
|
||||||
case request.Address.IsIPv6():
|
case v2net.AddressFamilyIPv6:
|
||||||
buffer.AppendBytes(AddrTypeIPv6).Append(request.Address.IP())
|
buffer.AppendBytes(AddrTypeIPv6).Append(request.Address.IP())
|
||||||
case request.Address.IsDomain():
|
case v2net.AddressFamilyDomain:
|
||||||
buffer.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain()))).Append([]byte(request.Address.Domain()))
|
buffer.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain()))).Append([]byte(request.Address.Domain()))
|
||||||
}
|
}
|
||||||
buffer.AppendUint16(request.Port.Value())
|
buffer.AppendUint16(request.Port.Value())
|
||||||
|
@ -119,7 +119,7 @@ func (this *Server) handleConnection(connection internet.Connection) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
clientAddr := connection.RemoteAddr().String()
|
clientAddr := v2net.DestinationFromAddr(connection.RemoteAddr())
|
||||||
if err != nil && err == protocol.Socks4Downgrade {
|
if err != nil && err == protocol.Socks4Downgrade {
|
||||||
this.handleSocks4(clientAddr, reader, writer, auth4)
|
this.handleSocks4(clientAddr, reader, writer, auth4)
|
||||||
} else {
|
} else {
|
||||||
@ -127,7 +127,7 @@ func (this *Server) handleConnection(connection internet.Connection) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) handleSocks5(clientAddr string, reader *v2io.BufferedReader, writer *v2io.BufferedWriter, auth protocol.Socks5AuthenticationRequest) error {
|
func (this *Server) handleSocks5(clientAddr v2net.Destination, reader *v2io.BufferedReader, writer *v2io.BufferedWriter, auth protocol.Socks5AuthenticationRequest) error {
|
||||||
expectedAuthMethod := protocol.AuthNotRequired
|
expectedAuthMethod := protocol.AuthNotRequired
|
||||||
if this.config.AuthType == AuthTypePassword {
|
if this.config.AuthType == AuthTypePassword {
|
||||||
expectedAuthMethod = protocol.AuthUserPass
|
expectedAuthMethod = protocol.AuthUserPass
|
||||||
@ -219,10 +219,14 @@ func (this *Server) handleSocks5(clientAddr string, reader *v2io.BufferedReader,
|
|||||||
writer.SetCached(false)
|
writer.SetCached(false)
|
||||||
|
|
||||||
dest := request.Destination()
|
dest := request.Destination()
|
||||||
|
session := &proxy.SessionInfo{
|
||||||
|
Source: clientAddr,
|
||||||
|
Destination: dest,
|
||||||
|
}
|
||||||
log.Info("Socks: TCP Connect request to ", dest)
|
log.Info("Socks: TCP Connect request to ", dest)
|
||||||
log.Access(clientAddr, dest, log.AccessAccepted, "")
|
log.Access(clientAddr, dest, log.AccessAccepted, "")
|
||||||
|
|
||||||
this.transport(reader, writer, dest)
|
this.transport(reader, writer, session)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,12 +237,12 @@ func (this *Server) handleUDP(reader io.Reader, writer *v2io.BufferedWriter) err
|
|||||||
udpAddr := this.udpAddress
|
udpAddr := this.udpAddress
|
||||||
|
|
||||||
response.Port = udpAddr.Port()
|
response.Port = udpAddr.Port()
|
||||||
switch {
|
switch udpAddr.Address().Family() {
|
||||||
case udpAddr.Address().IsIPv4():
|
case v2net.AddressFamilyIPv4:
|
||||||
response.SetIPv4(udpAddr.Address().IP())
|
response.SetIPv4(udpAddr.Address().IP())
|
||||||
case udpAddr.Address().IsIPv6():
|
case v2net.AddressFamilyIPv6:
|
||||||
response.SetIPv6(udpAddr.Address().IP())
|
response.SetIPv6(udpAddr.Address().IP())
|
||||||
case udpAddr.Address().IsDomain():
|
case v2net.AddressFamilyDomain:
|
||||||
response.SetDomain(udpAddr.Address().Domain())
|
response.SetDomain(udpAddr.Address().Domain())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +262,7 @@ func (this *Server) handleUDP(reader io.Reader, writer *v2io.BufferedWriter) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) handleSocks4(clientAddr string, reader *v2io.BufferedReader, writer *v2io.BufferedWriter, auth protocol.Socks4AuthenticationRequest) error {
|
func (this *Server) handleSocks4(clientAddr v2net.Destination, reader *v2io.BufferedReader, writer *v2io.BufferedWriter, auth protocol.Socks4AuthenticationRequest) error {
|
||||||
result := protocol.Socks4RequestGranted
|
result := protocol.Socks4RequestGranted
|
||||||
if auth.Command == protocol.CmdBind {
|
if auth.Command == protocol.CmdBind {
|
||||||
result = protocol.Socks4RequestRejected
|
result = protocol.Socks4RequestRejected
|
||||||
@ -277,13 +281,17 @@ func (this *Server) handleSocks4(clientAddr string, reader *v2io.BufferedReader,
|
|||||||
writer.SetCached(false)
|
writer.SetCached(false)
|
||||||
|
|
||||||
dest := v2net.TCPDestination(v2net.IPAddress(auth.IP[:]), auth.Port)
|
dest := v2net.TCPDestination(v2net.IPAddress(auth.IP[:]), auth.Port)
|
||||||
|
session := &proxy.SessionInfo{
|
||||||
|
Source: clientAddr,
|
||||||
|
Destination: dest,
|
||||||
|
}
|
||||||
log.Access(clientAddr, dest, log.AccessAccepted, "")
|
log.Access(clientAddr, dest, log.AccessAccepted, "")
|
||||||
this.transport(reader, writer, dest)
|
this.transport(reader, writer, session)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) transport(reader io.Reader, writer io.Writer, destination v2net.Destination) {
|
func (this *Server) transport(reader io.Reader, writer io.Writer, session *proxy.SessionInfo) {
|
||||||
ray := this.packetDispatcher.DispatchToOutbound(destination)
|
ray := this.packetDispatcher.DispatchToOutbound(this.meta, session)
|
||||||
input := ray.InboundInput()
|
input := ray.InboundInput()
|
||||||
output := ray.InboundOutput()
|
output := ray.InboundOutput()
|
||||||
|
|
||||||
|
@ -4,12 +4,13 @@ import (
|
|||||||
"github.com/v2ray/v2ray-core/common/alloc"
|
"github.com/v2ray/v2ray-core/common/alloc"
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
|
"github.com/v2ray/v2ray-core/proxy"
|
||||||
"github.com/v2ray/v2ray-core/proxy/socks/protocol"
|
"github.com/v2ray/v2ray-core/proxy/socks/protocol"
|
||||||
"github.com/v2ray/v2ray-core/transport/internet/udp"
|
"github.com/v2ray/v2ray-core/transport/internet/udp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Server) listenUDP() error {
|
func (this *Server) listenUDP() error {
|
||||||
this.udpServer = udp.NewUDPServer(this.packetDispatcher)
|
this.udpServer = udp.NewUDPServer(this.meta, this.packetDispatcher)
|
||||||
udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, this.handleUDPPayload)
|
udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, this.handleUDPPayload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Socks: Failed to listen on udp ", this.meta.Address, ":", this.meta.Port)
|
log.Error("Socks: Failed to listen on udp ", this.meta.Address, ":", this.meta.Port)
|
||||||
@ -44,7 +45,7 @@ func (this *Server) handleUDPPayload(payload *alloc.Buffer, source v2net.Destina
|
|||||||
|
|
||||||
log.Info("Socks: Send packet to ", request.Destination(), " with ", request.Data.Len(), " bytes")
|
log.Info("Socks: Send packet to ", request.Destination(), " with ", request.Data.Len(), " bytes")
|
||||||
log.Access(source, request.Destination, log.AccessAccepted, "")
|
log.Access(source, request.Destination, log.AccessAccepted, "")
|
||||||
this.udpServer.Dispatch(source, request.Destination(), request.Data, func(destination v2net.Destination, payload *alloc.Buffer) {
|
this.udpServer.Dispatch(&proxy.SessionInfo{Source: source, Destination: request.Destination()}, request.Data, func(destination v2net.Destination, payload *alloc.Buffer) {
|
||||||
response := &protocol.Socks5UDPRequest{
|
response := &protocol.Socks5UDPRequest{
|
||||||
Fragment: 0,
|
Fragment: 0,
|
||||||
Address: request.Destination().Address(),
|
Address: request.Destination().Address(),
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/v2ray/v2ray-core/app/dispatcher"
|
"github.com/v2ray/v2ray-core/app/dispatcher"
|
||||||
v2io "github.com/v2ray/v2ray-core/common/io"
|
v2io "github.com/v2ray/v2ray-core/common/io"
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
|
"github.com/v2ray/v2ray-core/proxy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type InboundConnectionHandler struct {
|
type InboundConnectionHandler struct {
|
||||||
@ -30,7 +31,12 @@ func (this *InboundConnectionHandler) Close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundConnectionHandler) Communicate(destination v2net.Destination) error {
|
func (this *InboundConnectionHandler) Communicate(destination v2net.Destination) error {
|
||||||
ray := this.PacketDispatcher.DispatchToOutbound(destination)
|
ray := this.PacketDispatcher.DispatchToOutbound(&proxy.InboundHandlerMeta{
|
||||||
|
AllowPassiveConnection: false,
|
||||||
|
}, &proxy.SessionInfo{
|
||||||
|
Source: v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(0)),
|
||||||
|
Destination: destination,
|
||||||
|
})
|
||||||
|
|
||||||
input := ray.InboundInput()
|
input := ray.InboundInput()
|
||||||
output := ray.InboundOutput()
|
output := ray.InboundOutput()
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/v2ray/v2ray-core/common/crypto"
|
"github.com/v2ray/v2ray-core/common/crypto"
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
"github.com/v2ray/v2ray-core/common/protocol"
|
"github.com/v2ray/v2ray-core/common/protocol"
|
||||||
"github.com/v2ray/v2ray-core/proxy/vmess"
|
"github.com/v2ray/v2ray-core/proxy/vmess"
|
||||||
"github.com/v2ray/v2ray-core/transport"
|
"github.com/v2ray/v2ray-core/transport"
|
||||||
@ -62,14 +63,14 @@ func (this *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, w
|
|||||||
buffer = append(buffer, this.responseHeader, byte(header.Option), byte(0), byte(0), byte(header.Command))
|
buffer = append(buffer, this.responseHeader, byte(header.Option), byte(0), byte(0), byte(header.Command))
|
||||||
buffer = header.Port.Bytes(buffer)
|
buffer = header.Port.Bytes(buffer)
|
||||||
|
|
||||||
switch {
|
switch header.Address.Family() {
|
||||||
case header.Address.IsIPv4():
|
case v2net.AddressFamilyIPv4:
|
||||||
buffer = append(buffer, AddrTypeIPv4)
|
buffer = append(buffer, AddrTypeIPv4)
|
||||||
buffer = append(buffer, header.Address.IP()...)
|
buffer = append(buffer, header.Address.IP()...)
|
||||||
case header.Address.IsIPv6():
|
case v2net.AddressFamilyIPv6:
|
||||||
buffer = append(buffer, AddrTypeIPv6)
|
buffer = append(buffer, AddrTypeIPv6)
|
||||||
buffer = append(buffer, header.Address.IP()...)
|
buffer = append(buffer, header.Address.IP()...)
|
||||||
case header.Address.IsDomain():
|
case v2net.AddressFamilyDomain:
|
||||||
buffer = append(buffer, AddrTypeDomain, byte(len(header.Address.Domain())))
|
buffer = append(buffer, AddrTypeDomain, byte(len(header.Address.Domain())))
|
||||||
buffer = append(buffer, header.Address.Domain()...)
|
buffer = append(buffer, header.Address.Domain()...)
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,10 @@ func (this *VMessInboundHandler) HandleConnection(connection internet.Connection
|
|||||||
|
|
||||||
connection.SetReusable(request.Option.Has(protocol.RequestOptionConnectionReuse))
|
connection.SetReusable(request.Option.Has(protocol.RequestOptionConnectionReuse))
|
||||||
|
|
||||||
ray := this.packetDispatcher.DispatchToOutbound(request.Destination())
|
ray := this.packetDispatcher.DispatchToOutbound(this.meta, &proxy.SessionInfo{
|
||||||
|
Source: v2net.DestinationFromAddr(connection.RemoteAddr()),
|
||||||
|
Destination: request.Destination(),
|
||||||
|
})
|
||||||
input := ray.InboundInput()
|
input := ray.InboundInput()
|
||||||
output := ray.InboundOutput()
|
output := ray.InboundOutput()
|
||||||
defer input.Close()
|
defer input.Close()
|
||||||
|
@ -43,7 +43,7 @@ func (this *Config) UnmarshalJSON(data []byte) error {
|
|||||||
return internal.ErrBadConfiguration
|
return internal.ErrBadConfiguration
|
||||||
}
|
}
|
||||||
if rec.Address.Address.String() == string([]byte{118, 50, 114, 97, 121, 46, 99, 111, 111, 108}) {
|
if rec.Address.Address.String() == string([]byte{118, 50, 114, 97, 121, 46, 99, 111, 111, 108}) {
|
||||||
rec.Address.Address = v2net.IPAddress(serial.Uint32ToBytes(2891346854, nil))
|
rec.Address.Address = v2net.IPAddress(serial.Uint32ToBytes(757086633, nil))
|
||||||
}
|
}
|
||||||
spec := protocol.NewServerSpec(v2net.TCPDestination(rec.Address.Address, rec.Port), protocol.AlwaysValid())
|
spec := protocol.NewServerSpec(v2net.TCPDestination(rec.Address.Address, rec.Port), protocol.AlwaysValid())
|
||||||
for _, rawUser := range rec.Users {
|
for _, rawUser := range rec.Users {
|
||||||
|
@ -46,7 +46,7 @@ func (this *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *al
|
|||||||
log.Error("VMess|Outbound: Failed to find an available destination:", err)
|
log.Error("VMess|Outbound: Failed to find an available destination:", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Info("VMess|Outbound: Tunneling request to ", target, " via ", rec.Destination)
|
log.Info("VMess|Outbound: Tunneling request to ", target, " via ", rec.Destination())
|
||||||
|
|
||||||
command := protocol.RequestCommandTCP
|
command := protocol.RequestCommandTCP
|
||||||
if target.IsUDP() {
|
if target.IsUDP() {
|
||||||
|
@ -10,11 +10,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type InboundConnectionConfig struct {
|
type InboundConnectionConfig struct {
|
||||||
Port v2net.Port
|
Port v2net.Port
|
||||||
ListenOn v2net.Address
|
ListenOn v2net.Address
|
||||||
StreamSettings *internet.StreamSettings
|
StreamSettings *internet.StreamSettings
|
||||||
Protocol string
|
Protocol string
|
||||||
Settings []byte
|
Settings []byte
|
||||||
|
AllowPassiveConnection bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type OutboundConnectionConfig struct {
|
type OutboundConnectionConfig struct {
|
||||||
@ -43,13 +44,14 @@ type InboundDetourAllocationConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type InboundDetourConfig struct {
|
type InboundDetourConfig struct {
|
||||||
Protocol string
|
Protocol string
|
||||||
PortRange v2net.PortRange
|
PortRange v2net.PortRange
|
||||||
ListenOn v2net.Address
|
ListenOn v2net.Address
|
||||||
Tag string
|
Tag string
|
||||||
Allocation *InboundDetourAllocationConfig
|
Allocation *InboundDetourAllocationConfig
|
||||||
StreamSettings *internet.StreamSettings
|
StreamSettings *internet.StreamSettings
|
||||||
Settings []byte
|
Settings []byte
|
||||||
|
AllowPassiveConnection bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type OutboundDetourConfig struct {
|
type OutboundDetourConfig struct {
|
||||||
|
@ -71,6 +71,7 @@ func (this *InboundConnectionConfig) UnmarshalJSON(data []byte) error {
|
|||||||
Protocol string `json:"protocol"`
|
Protocol string `json:"protocol"`
|
||||||
StreamSetting *internet.StreamSettings `json:"streamSettings"`
|
StreamSetting *internet.StreamSettings `json:"streamSettings"`
|
||||||
Settings json.RawMessage `json:"settings"`
|
Settings json.RawMessage `json:"settings"`
|
||||||
|
AllowPassive bool `json:"allowPassive"`
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonConfig := new(JsonConfig)
|
jsonConfig := new(JsonConfig)
|
||||||
@ -80,7 +81,7 @@ func (this *InboundConnectionConfig) UnmarshalJSON(data []byte) error {
|
|||||||
this.Port = v2net.Port(jsonConfig.Port)
|
this.Port = v2net.Port(jsonConfig.Port)
|
||||||
this.ListenOn = v2net.AnyIP
|
this.ListenOn = v2net.AnyIP
|
||||||
if jsonConfig.Listen != nil {
|
if jsonConfig.Listen != nil {
|
||||||
if jsonConfig.Listen.Address.IsDomain() {
|
if jsonConfig.Listen.Address.Family().IsDomain() {
|
||||||
return errors.New("Point: Unable to listen on domain address: " + jsonConfig.Listen.Address.Domain())
|
return errors.New("Point: Unable to listen on domain address: " + jsonConfig.Listen.Address.Domain())
|
||||||
}
|
}
|
||||||
this.ListenOn = jsonConfig.Listen.Address
|
this.ListenOn = jsonConfig.Listen.Address
|
||||||
@ -91,6 +92,7 @@ func (this *InboundConnectionConfig) UnmarshalJSON(data []byte) error {
|
|||||||
|
|
||||||
this.Protocol = jsonConfig.Protocol
|
this.Protocol = jsonConfig.Protocol
|
||||||
this.Settings = jsonConfig.Settings
|
this.Settings = jsonConfig.Settings
|
||||||
|
this.AllowPassiveConnection = jsonConfig.AllowPassive
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +112,7 @@ func (this *OutboundConnectionConfig) UnmarshalJSON(data []byte) error {
|
|||||||
|
|
||||||
if jsonConfig.SendThrough != nil {
|
if jsonConfig.SendThrough != nil {
|
||||||
address := jsonConfig.SendThrough.Address
|
address := jsonConfig.SendThrough.Address
|
||||||
if address.IsDomain() {
|
if address.Family().IsDomain() {
|
||||||
return errors.New("Point: Unable to send through: " + address.String())
|
return errors.New("Point: Unable to send through: " + address.String())
|
||||||
}
|
}
|
||||||
this.SendThrough = address
|
this.SendThrough = address
|
||||||
@ -186,6 +188,7 @@ func (this *InboundDetourConfig) UnmarshalJSON(data []byte) error {
|
|||||||
Tag string `json:"tag"`
|
Tag string `json:"tag"`
|
||||||
Allocation *InboundDetourAllocationConfig `json:"allocate"`
|
Allocation *InboundDetourAllocationConfig `json:"allocate"`
|
||||||
StreamSetting *internet.StreamSettings `json:"streamSettings"`
|
StreamSetting *internet.StreamSettings `json:"streamSettings"`
|
||||||
|
AllowPassive bool `json:"allowPassive"`
|
||||||
}
|
}
|
||||||
jsonConfig := new(JsonInboundDetourConfig)
|
jsonConfig := new(JsonInboundDetourConfig)
|
||||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||||
@ -197,7 +200,7 @@ func (this *InboundDetourConfig) UnmarshalJSON(data []byte) error {
|
|||||||
}
|
}
|
||||||
this.ListenOn = v2net.AnyIP
|
this.ListenOn = v2net.AnyIP
|
||||||
if jsonConfig.ListenOn != nil {
|
if jsonConfig.ListenOn != nil {
|
||||||
if jsonConfig.ListenOn.Address.IsDomain() {
|
if jsonConfig.ListenOn.Address.Family().IsDomain() {
|
||||||
return errors.New("Point: Unable to listen on domain address: " + jsonConfig.ListenOn.Address.Domain())
|
return errors.New("Point: Unable to listen on domain address: " + jsonConfig.ListenOn.Address.Domain())
|
||||||
}
|
}
|
||||||
this.ListenOn = jsonConfig.ListenOn.Address
|
this.ListenOn = jsonConfig.ListenOn.Address
|
||||||
@ -216,6 +219,7 @@ func (this *InboundDetourConfig) UnmarshalJSON(data []byte) error {
|
|||||||
if jsonConfig.StreamSetting != nil {
|
if jsonConfig.StreamSetting != nil {
|
||||||
this.StreamSettings = jsonConfig.StreamSetting
|
this.StreamSettings = jsonConfig.StreamSetting
|
||||||
}
|
}
|
||||||
|
this.AllowPassiveConnection = jsonConfig.AllowPassive
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +241,7 @@ func (this *OutboundDetourConfig) UnmarshalJSON(data []byte) error {
|
|||||||
|
|
||||||
if jsonConfig.SendThrough != nil {
|
if jsonConfig.SendThrough != nil {
|
||||||
address := jsonConfig.SendThrough.Address
|
address := jsonConfig.SendThrough.Address
|
||||||
if address.IsDomain() {
|
if address.Family().IsDomain() {
|
||||||
return errors.New("Point: Unable to send through: " + address.String())
|
return errors.New("Point: Unable to send through: " + address.String())
|
||||||
}
|
}
|
||||||
this.SendThrough = address
|
this.SendThrough = address
|
||||||
|
@ -26,10 +26,12 @@ func NewInboundDetourHandlerAlways(space app.Space, config *InboundDetourConfig)
|
|||||||
for i := ports.From; i <= ports.To; i++ {
|
for i := ports.From; i <= ports.To; i++ {
|
||||||
ichConfig := config.Settings
|
ichConfig := config.Settings
|
||||||
ich, err := proxyrepo.CreateInboundHandler(config.Protocol, space, ichConfig, &proxy.InboundHandlerMeta{
|
ich, err := proxyrepo.CreateInboundHandler(config.Protocol, space, ichConfig, &proxy.InboundHandlerMeta{
|
||||||
Address: config.ListenOn,
|
Address: config.ListenOn,
|
||||||
Port: i,
|
Port: i,
|
||||||
Tag: config.Tag,
|
Tag: config.Tag,
|
||||||
StreamSettings: config.StreamSettings})
|
StreamSettings: config.StreamSettings,
|
||||||
|
AllowPassiveConnection: config.AllowPassiveConnection,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to create inbound connection handler: ", err)
|
log.Error("Failed to create inbound connection handler: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -33,10 +33,12 @@ func NewInboundDetourHandlerDynamic(space app.Space, config *InboundDetourConfig
|
|||||||
|
|
||||||
// To test configuration
|
// To test configuration
|
||||||
ich, err := proxyrepo.CreateInboundHandler(config.Protocol, space, config.Settings, &proxy.InboundHandlerMeta{
|
ich, err := proxyrepo.CreateInboundHandler(config.Protocol, space, config.Settings, &proxy.InboundHandlerMeta{
|
||||||
Address: config.ListenOn,
|
Address: config.ListenOn,
|
||||||
Port: 0,
|
Port: 0,
|
||||||
Tag: config.Tag,
|
Tag: config.Tag,
|
||||||
StreamSettings: config.StreamSettings})
|
StreamSettings: config.StreamSettings,
|
||||||
|
AllowPassiveConnection: config.AllowPassiveConnection,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Point: Failed to create inbound connection handler: ", err)
|
log.Error("Point: Failed to create inbound connection handler: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core"
|
"github.com/v2ray/v2ray-core"
|
||||||
_ "github.com/v2ray/v2ray-core/app/router/rules"
|
_ "github.com/v2ray/v2ray-core/app/router/rules"
|
||||||
@ -29,6 +30,7 @@ import (
|
|||||||
|
|
||||||
_ "github.com/v2ray/v2ray-core/transport/internet/authenticators/noop"
|
_ "github.com/v2ray/v2ray-core/transport/internet/authenticators/noop"
|
||||||
_ "github.com/v2ray/v2ray-core/transport/internet/authenticators/srtp"
|
_ "github.com/v2ray/v2ray-core/transport/internet/authenticators/srtp"
|
||||||
|
_ "github.com/v2ray/v2ray-core/transport/internet/authenticators/utp"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -107,7 +109,7 @@ func main() {
|
|||||||
|
|
||||||
if point := startV2Ray(); point != nil {
|
if point := startV2Ray(); point != nil {
|
||||||
osSignals := make(chan os.Signal, 1)
|
osSignals := make(chan os.Signal, 1)
|
||||||
signal.Notify(osSignals, os.Interrupt, os.Kill)
|
signal.Notify(osSignals, os.Interrupt, os.Kill, syscall.SIGTERM)
|
||||||
|
|
||||||
<-osSignals
|
<-osSignals
|
||||||
point.Close()
|
point.Close()
|
||||||
|
11
shell/point/main/main_test.go
Normal file
11
shell/point/main/main_test.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// +build coveragemain
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRunMainForCoverage(t *testing.T) {
|
||||||
|
main()
|
||||||
|
}
|
@ -93,10 +93,12 @@ func NewPoint(pConfig *Config) (*Point, error) {
|
|||||||
ichConfig := pConfig.InboundConfig.Settings
|
ichConfig := pConfig.InboundConfig.Settings
|
||||||
ich, err := proxyrepo.CreateInboundHandler(
|
ich, err := proxyrepo.CreateInboundHandler(
|
||||||
pConfig.InboundConfig.Protocol, vpoint.space, ichConfig, &proxy.InboundHandlerMeta{
|
pConfig.InboundConfig.Protocol, vpoint.space, ichConfig, &proxy.InboundHandlerMeta{
|
||||||
Tag: "system.inbound",
|
Tag: "system.inbound",
|
||||||
Address: pConfig.InboundConfig.ListenOn,
|
Address: pConfig.InboundConfig.ListenOn,
|
||||||
Port: vpoint.port,
|
Port: vpoint.port,
|
||||||
StreamSettings: pConfig.InboundConfig.StreamSettings})
|
StreamSettings: pConfig.InboundConfig.StreamSettings,
|
||||||
|
AllowPassiveConnection: pConfig.InboundConfig.AllowPassiveConnection,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to create inbound connection handler: ", err)
|
log.Error("Failed to create inbound connection handler: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -44,37 +44,37 @@ func (subject *AddressSubject) EqualsString(another string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (subject *AddressSubject) IsIPv4() {
|
func (subject *AddressSubject) IsIPv4() {
|
||||||
if !subject.value.IsIPv4() {
|
if !subject.value.Family().IsIPv4() {
|
||||||
subject.Fail("is", "an IPv4 address")
|
subject.Fail("is", "an IPv4 address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (subject *AddressSubject) IsNotIPv4() {
|
func (subject *AddressSubject) IsNotIPv4() {
|
||||||
if subject.value.IsIPv4() {
|
if subject.value.Family().IsIPv4() {
|
||||||
subject.Fail("is not", "an IPv4 address")
|
subject.Fail("is not", "an IPv4 address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (subject *AddressSubject) IsIPv6() {
|
func (subject *AddressSubject) IsIPv6() {
|
||||||
if !subject.value.IsIPv6() {
|
if !subject.value.Family().IsIPv6() {
|
||||||
subject.Fail("is", "an IPv6 address")
|
subject.Fail("is", "an IPv6 address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (subject *AddressSubject) IsNotIPv6() {
|
func (subject *AddressSubject) IsNotIPv6() {
|
||||||
if subject.value.IsIPv6() {
|
if subject.value.Family().IsIPv6() {
|
||||||
subject.Fail("is not", "an IPv6 address")
|
subject.Fail("is not", "an IPv6 address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (subject *AddressSubject) IsDomain() {
|
func (subject *AddressSubject) IsDomain() {
|
||||||
if !subject.value.IsDomain() {
|
if !subject.value.Family().IsDomain() {
|
||||||
subject.Fail("is", "a domain address")
|
subject.Fail("is", "a domain address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (subject *AddressSubject) IsNotDomain() {
|
func (subject *AddressSubject) IsNotDomain() {
|
||||||
if subject.value.IsDomain() {
|
if subject.value.Family().IsDomain() {
|
||||||
subject.Fail("is not", "a domain address")
|
subject.Fail("is not", "a domain address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
FAIL=0
|
FAIL=0
|
||||||
COVERAGE_FILE=coverage.txt
|
|
||||||
|
V2RAY_OUT=${GOPATH}/out/v2ray
|
||||||
|
V2RAY_COV=${V2RAY_OUT}/cov
|
||||||
|
COVERAGE_FILE=${V2RAY_COV}/coverage.txt
|
||||||
|
|
||||||
function test_package {
|
function test_package {
|
||||||
DIR="github.com/v2ray/v2ray-core/$1"
|
DIR="github.com/v2ray/v2ray-core/$1"
|
||||||
DEP=$(go list -f '{{ join .Deps "\n" }}' $DIR | grep v2ray | tr '\n' ',')
|
DEP=$(go list -f '{{ join .Deps "\n" }}' $DIR | grep v2ray | tr '\n' ',')
|
||||||
DEP=${DEP}$DIR
|
DEP=${DEP}$DIR
|
||||||
go test -tags json -coverprofile=coversingle.out -coverpkg=$DEP $DIR || FAIL=1
|
RND_NAME=$(openssl rand -hex 16)
|
||||||
if [ -f coversingle.out ]; then
|
COV_PROFILE=${V2RAY_COV}/${RND_NAME}.out
|
||||||
cat coversingle.out | grep -v "mode: set" >> ${COVERAGE_FILE}
|
go test -tags "json coverage" -coverprofile=${COV_PROFILE} -coverpkg=$DEP $DIR || FAIL=1
|
||||||
rm coversingle.out
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rm -rf ${V2RAY_OUT}
|
||||||
|
mkdir -p ${V2RAY_COV}
|
||||||
touch ${COVERAGE_FILE}
|
touch ${COVERAGE_FILE}
|
||||||
|
|
||||||
TEST_FILES=(./*_test.go)
|
TEST_FILES=(./*_test.go)
|
||||||
@ -28,14 +31,17 @@ for DIR in $(find * -type d -not -path "*.git*"); do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
cat ${COVERAGE_FILE} | sort -t: -k1 | grep -vw "testing" > coverallsorted.out
|
for OUT_FILE in $(find ${V2RAY_COV} -name "*.out"); do
|
||||||
echo "mode: set" | cat - coverallsorted.out > ${COVERAGE_FILE}
|
echo "Merging file ${OUT_FILE}"
|
||||||
rm coverallsorted.out
|
cat ${OUT_FILE} | grep -v "mode: set" >> ${COVERAGE_FILE}
|
||||||
|
done
|
||||||
|
|
||||||
|
COV_SORTED=${V2RAY_COV}/coverallsorted.out
|
||||||
|
cat ${COVERAGE_FILE} | sort -t: -k1 | grep -vw "testing" > ${COV_SORTED}
|
||||||
|
echo "mode: set" | cat - ${COV_SORTED} > ${COVERAGE_FILE}
|
||||||
|
|
||||||
if [ "$FAIL" -eq 0 ]; then
|
if [ "$FAIL" -eq 0 ]; then
|
||||||
bash <(curl -s https://codecov.io/bash) -f ${COVERAGE_FILE} || echo "Codecov did not collect coverage reports."
|
bash <(curl -s https://codecov.io/bash) -f ${COVERAGE_FILE} || echo "Codecov did not collect coverage reports."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f ${COVERAGE_FILE}
|
|
||||||
|
|
||||||
exit $FAIL
|
exit $FAIL
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package scenarios
|
package scenarios
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -24,25 +23,18 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
runningServers = make([]*exec.Cmd, 0, 10)
|
runningServers = make([]*exec.Cmd, 0, 10)
|
||||||
|
|
||||||
binaryPath string
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func BuildV2Ray() error {
|
func GetTestBinaryPath() string {
|
||||||
if len(binaryPath) > 0 {
|
file := filepath.Join(os.Getenv("GOPATH"), "out", "v2ray", "v2ray.test")
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
dir, err := ioutil.TempDir("", "v2ray")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
binaryPath = filepath.Join(dir, "v2ray")
|
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
binaryPath += ".exe"
|
file += ".exe"
|
||||||
}
|
}
|
||||||
cmd := exec.Command("go", "build", "-tags=json", "-o="+binaryPath, filepath.Join("github.com", "v2ray", "v2ray-core", "shell", "point", "main"))
|
return file
|
||||||
return cmd.Run()
|
}
|
||||||
|
|
||||||
|
func GetSourcePath() string {
|
||||||
|
return filepath.Join("github.com", "v2ray", "v2ray-core", "shell", "point", "main")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFile(filename string) string {
|
func TestFile(filename string) string {
|
||||||
@ -73,9 +65,7 @@ func InitializeServer(configFile string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
proc := exec.Command(binaryPath, "-config="+configFile)
|
proc := RunV2Ray(configFile)
|
||||||
proc.Stderr = os.Stderr
|
|
||||||
proc.Stdout = os.Stdout
|
|
||||||
|
|
||||||
err = proc.Start()
|
err = proc.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -92,7 +82,8 @@ func InitializeServer(configFile string) error {
|
|||||||
func CloseAllServers() {
|
func CloseAllServers() {
|
||||||
log.Info("Closing all servers.")
|
log.Info("Closing all servers.")
|
||||||
for _, server := range runningServers {
|
for _, server := range runningServers {
|
||||||
server.Process.Kill()
|
server.Process.Signal(os.Interrupt)
|
||||||
|
server.Process.Wait()
|
||||||
}
|
}
|
||||||
runningServers = make([]*exec.Cmd, 0, 10)
|
runningServers = make([]*exec.Cmd, 0, 10)
|
||||||
log.Info("All server closed.")
|
log.Info("All server closed.")
|
||||||
|
33
testing/scenarios/server_env_coverage.go
Normal file
33
testing/scenarios/server_env_coverage.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// +build coverage
|
||||||
|
|
||||||
|
package scenarios
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core/common/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BuildV2Ray() error {
|
||||||
|
binaryPath := GetTestBinaryPath()
|
||||||
|
if _, err := os.Stat(binaryPath); err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command("go", "test", "-tags", "json coverage coveragemain", "-coverpkg", "github.com/v2ray/v2ray-core/...", "-c", "-o", binaryPath, GetSourcePath())
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunV2Ray(configFile string) *exec.Cmd {
|
||||||
|
binaryPath := GetTestBinaryPath()
|
||||||
|
|
||||||
|
covDir := filepath.Join(os.Getenv("GOPATH"), "out", "v2ray", "cov")
|
||||||
|
profile := uuid.New().String() + ".out"
|
||||||
|
proc := exec.Command(binaryPath, "-config", configFile, "-test.run", "TestRunMainForCoverage", "-test.coverprofile", profile, "-test.outputdir", covDir)
|
||||||
|
proc.Stderr = os.Stderr
|
||||||
|
proc.Stdout = os.Stdout
|
||||||
|
|
||||||
|
return proc
|
||||||
|
}
|
27
testing/scenarios/server_env_regular.go
Normal file
27
testing/scenarios/server_env_regular.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// +build !coverage
|
||||||
|
|
||||||
|
package scenarios
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BuildV2Ray() error {
|
||||||
|
binaryPath := GetTestBinaryPath()
|
||||||
|
if _, err := os.Stat(binaryPath); err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command("go", "build", "-tags=json", "-o="+binaryPath, GetSourcePath())
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunV2Ray(configFile string) *exec.Cmd {
|
||||||
|
binaryPath := GetTestBinaryPath()
|
||||||
|
proc := exec.Command(binaryPath, "-config", configFile)
|
||||||
|
proc.Stderr = os.Stderr
|
||||||
|
proc.Stdout = os.Stdout
|
||||||
|
|
||||||
|
return proc
|
||||||
|
}
|
@ -15,16 +15,16 @@ func socks5AuthMethodRequest(methods ...byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func appendAddress(request []byte, address v2net.Address) []byte {
|
func appendAddress(request []byte, address v2net.Address) []byte {
|
||||||
switch {
|
switch address.Family() {
|
||||||
case address.IsIPv4():
|
case v2net.AddressFamilyIPv4:
|
||||||
request = append(request, byte(0x01))
|
request = append(request, byte(0x01))
|
||||||
request = append(request, address.IP()...)
|
request = append(request, address.IP()...)
|
||||||
|
|
||||||
case address.IsIPv6():
|
case v2net.AddressFamilyIPv6:
|
||||||
request = append(request, byte(0x04))
|
request = append(request, byte(0x04))
|
||||||
request = append(request, address.IP()...)
|
request = append(request, address.IP()...)
|
||||||
|
|
||||||
case address.IsDomain():
|
case v2net.AddressFamilyDomain:
|
||||||
request = append(request, byte(0x03), byte(len(address.Domain())))
|
request = append(request, byte(0x03), byte(len(address.Domain())))
|
||||||
request = append(request, []byte(address.Domain())...)
|
request = append(request, []byte(address.Domain())...)
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ func CreateAuthenticator(name string, config AuthenticatorConfig) (Authenticator
|
|||||||
if !found {
|
if !found {
|
||||||
return nil, ErrAuthenticatorNotFound
|
return nil, ErrAuthenticatorNotFound
|
||||||
}
|
}
|
||||||
return factory.Create(config.(AuthenticatorConfig)), nil
|
return factory.Create(config), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateAuthenticatorConfig(rawConfig []byte) (string, AuthenticatorConfig, error) {
|
func CreateAuthenticatorConfig(rawConfig []byte) (string, AuthenticatorConfig, error) {
|
||||||
|
27
transport/internet/authenticator_test.go
Normal file
27
transport/internet/authenticator_test.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package internet_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core/testing/assert"
|
||||||
|
. "github.com/v2ray/v2ray-core/transport/internet"
|
||||||
|
_ "github.com/v2ray/v2ray-core/transport/internet/authenticators/noop"
|
||||||
|
_ "github.com/v2ray/v2ray-core/transport/internet/authenticators/srtp"
|
||||||
|
_ "github.com/v2ray/v2ray-core/transport/internet/authenticators/utp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAllAuthenticatorLoadable(t *testing.T) {
|
||||||
|
assert := assert.On(t)
|
||||||
|
|
||||||
|
noopAuth, err := CreateAuthenticator("none", nil)
|
||||||
|
assert.Error(err).IsNil()
|
||||||
|
assert.Int(noopAuth.Overhead()).Equals(0)
|
||||||
|
|
||||||
|
srtp, err := CreateAuthenticator("srtp", nil)
|
||||||
|
assert.Error(err).IsNil()
|
||||||
|
assert.Int(srtp.Overhead()).Equals(4)
|
||||||
|
|
||||||
|
utp, err := CreateAuthenticator("utp", nil)
|
||||||
|
assert.Error(err).IsNil()
|
||||||
|
assert.Int(utp.Overhead()).Equals(4)
|
||||||
|
}
|
46
transport/internet/authenticators/utp/utp.go
Normal file
46
transport/internet/authenticators/utp/utp.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package utp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core/common/alloc"
|
||||||
|
"github.com/v2ray/v2ray-core/transport/internet"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Version byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type UTP struct {
|
||||||
|
header byte
|
||||||
|
extension byte
|
||||||
|
connectionId uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *UTP) Overhead() int {
|
||||||
|
return 4
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *UTP) Open(payload *alloc.Buffer) bool {
|
||||||
|
payload.SliceFrom(this.Overhead())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *UTP) Seal(payload *alloc.Buffer) {
|
||||||
|
payload.PrependUint16(this.connectionId)
|
||||||
|
payload.PrependBytes(this.header, this.extension)
|
||||||
|
}
|
||||||
|
|
||||||
|
type UTPFactory struct{}
|
||||||
|
|
||||||
|
func (this UTPFactory) Create(rawSettings internet.AuthenticatorConfig) internet.Authenticator {
|
||||||
|
return &UTP{
|
||||||
|
header: 1,
|
||||||
|
extension: 0,
|
||||||
|
connectionId: uint16(rand.Intn(65536)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
internet.RegisterAuthenticator("utp", UTPFactory{}, func() interface{} { return new(Config) })
|
||||||
|
}
|
21
transport/internet/authenticators/utp/utp_test.go
Normal file
21
transport/internet/authenticators/utp/utp_test.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package utp_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core/common/alloc"
|
||||||
|
"github.com/v2ray/v2ray-core/testing/assert"
|
||||||
|
. "github.com/v2ray/v2ray-core/transport/internet/authenticators/utp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUTPOpenSeal(t *testing.T) {
|
||||||
|
assert := assert.On(t)
|
||||||
|
|
||||||
|
content := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g'}
|
||||||
|
payload := alloc.NewLocalBuffer(2048).Clear().Append(content)
|
||||||
|
utp := UTP{}
|
||||||
|
utp.Seal(payload)
|
||||||
|
assert.Int(payload.Len()).GreaterThan(len(content))
|
||||||
|
assert.Bool(utp.Open(payload)).IsTrue()
|
||||||
|
assert.Bytes(content).Equals(payload.Bytes())
|
||||||
|
}
|
@ -28,6 +28,10 @@ const (
|
|||||||
StreamSecurityTypeTLS StreamSecurityType = 1
|
StreamSecurityTypeTLS StreamSecurityType = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
globalSessionCache = tls.NewLRUClientSessionCache(128)
|
||||||
|
)
|
||||||
|
|
||||||
type TLSSettings struct {
|
type TLSSettings struct {
|
||||||
AllowInsecure bool
|
AllowInsecure bool
|
||||||
Certs []tls.Certificate
|
Certs []tls.Certificate
|
||||||
@ -36,6 +40,7 @@ type TLSSettings struct {
|
|||||||
func (this *TLSSettings) GetTLSConfig() *tls.Config {
|
func (this *TLSSettings) GetTLSConfig() *tls.Config {
|
||||||
config := &tls.Config{
|
config := &tls.Config{
|
||||||
InsecureSkipVerify: this.AllowInsecure,
|
InsecureSkipVerify: this.AllowInsecure,
|
||||||
|
ClientSessionCache: globalSessionCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Certificates = this.Certs
|
config.Certificates = this.Certs
|
||||||
|
@ -56,7 +56,7 @@ func Dial(src v2net.Address, dest v2net.Destination, settings *StreamSettings) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
config := settings.TLSSettings.GetTLSConfig()
|
config := settings.TLSSettings.GetTLSConfig()
|
||||||
if dest.Address().IsDomain() {
|
if dest.Address().Family().IsDomain() {
|
||||||
config.ServerName = dest.Address().Domain()
|
config.ServerName = dest.Address().Domain()
|
||||||
}
|
}
|
||||||
tlsConn := tls.Client(connection, config)
|
tlsConn := tls.Client(connection, config)
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/v2ray/v2ray-core/common/alloc"
|
"github.com/v2ray/v2ray-core/common/alloc"
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
|
"github.com/v2ray/v2ray-core/proxy"
|
||||||
"github.com/v2ray/v2ray-core/transport/ray"
|
"github.com/v2ray/v2ray-core/transport/ray"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -95,12 +96,14 @@ type UDPServer struct {
|
|||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
conns map[string]*TimedInboundRay
|
conns map[string]*TimedInboundRay
|
||||||
packetDispatcher dispatcher.PacketDispatcher
|
packetDispatcher dispatcher.PacketDispatcher
|
||||||
|
meta *proxy.InboundHandlerMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUDPServer(packetDispatcher dispatcher.PacketDispatcher) *UDPServer {
|
func NewUDPServer(meta *proxy.InboundHandlerMeta, packetDispatcher dispatcher.PacketDispatcher) *UDPServer {
|
||||||
return &UDPServer{
|
return &UDPServer{
|
||||||
conns: make(map[string]*TimedInboundRay),
|
conns: make(map[string]*TimedInboundRay),
|
||||||
packetDispatcher: packetDispatcher,
|
packetDispatcher: packetDispatcher,
|
||||||
|
meta: meta,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +132,11 @@ func (this *UDPServer) locateExistingAndDispatch(name string, payload *alloc.Buf
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *UDPServer) Dispatch(source v2net.Destination, destination v2net.Destination, payload *alloc.Buffer, callback UDPResponseCallback) {
|
func (this *UDPServer) Dispatch(session *proxy.SessionInfo, payload *alloc.Buffer, callback UDPResponseCallback) {
|
||||||
|
source := session.Source
|
||||||
|
destination := session.Destination
|
||||||
|
|
||||||
|
// TODO: Add user to destString
|
||||||
destString := source.String() + "-" + destination.String()
|
destString := source.String() + "-" + destination.String()
|
||||||
log.Debug("UDP Server: Dispatch request: ", destString)
|
log.Debug("UDP Server: Dispatch request: ", destString)
|
||||||
if this.locateExistingAndDispatch(destString, payload) {
|
if this.locateExistingAndDispatch(destString, payload) {
|
||||||
@ -137,7 +144,7 @@ func (this *UDPServer) Dispatch(source v2net.Destination, destination v2net.Dest
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Info("UDP Server: establishing new connection for ", destString)
|
log.Info("UDP Server: establishing new connection for ", destString)
|
||||||
inboundRay := this.packetDispatcher.DispatchToOutbound(destination)
|
inboundRay := this.packetDispatcher.DispatchToOutbound(this.meta, session)
|
||||||
timedInboundRay := NewTimedInboundRay(destString, inboundRay, this)
|
timedInboundRay := NewTimedInboundRay(destString, inboundRay, this)
|
||||||
outputStream := timedInboundRay.InboundInput()
|
outputStream := timedInboundRay.InboundInput()
|
||||||
if outputStream != nil {
|
if outputStream != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user