mirror of https://github.com/v2ray/v2ray-core
rename 'this'
parent
d00f8eef56
commit
f95c322677
|
@ -26,31 +26,31 @@ func NewDefaultDispatcher(space app.Space) *DefaultDispatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private: Used by app.Space only.
|
// Private: Used by app.Space only.
|
||||||
func (this *DefaultDispatcher) Initialize(space app.Space) error {
|
func (v *DefaultDispatcher) Initialize(space app.Space) error {
|
||||||
if !space.HasApp(proxyman.APP_ID_OUTBOUND_MANAGER) {
|
if !space.HasApp(proxyman.APP_ID_OUTBOUND_MANAGER) {
|
||||||
return errors.New("DefaultDispatcher: OutboundHandlerManager is not found in the space.")
|
return errors.New("DefaultDispatcher: OutboundHandlerManager is not found in the space.")
|
||||||
}
|
}
|
||||||
this.ohm = space.GetApp(proxyman.APP_ID_OUTBOUND_MANAGER).(proxyman.OutboundHandlerManager)
|
v.ohm = space.GetApp(proxyman.APP_ID_OUTBOUND_MANAGER).(proxyman.OutboundHandlerManager)
|
||||||
|
|
||||||
if space.HasApp(router.APP_ID) {
|
if space.HasApp(router.APP_ID) {
|
||||||
this.router = space.GetApp(router.APP_ID).(*router.Router)
|
v.router = space.GetApp(router.APP_ID).(*router.Router)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DefaultDispatcher) Release() {
|
func (v *DefaultDispatcher) Release() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DefaultDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay {
|
func (v *DefaultDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay {
|
||||||
direct := ray.NewRay()
|
direct := ray.NewRay()
|
||||||
dispatcher := this.ohm.GetDefaultHandler()
|
dispatcher := v.ohm.GetDefaultHandler()
|
||||||
destination := session.Destination
|
destination := session.Destination
|
||||||
|
|
||||||
if this.router != nil {
|
if v.router != nil {
|
||||||
if tag, err := this.router.TakeDetour(session); err == nil {
|
if tag, err := v.router.TakeDetour(session); err == nil {
|
||||||
if handler := this.ohm.GetHandler(tag); handler != nil {
|
if handler := v.ohm.GetHandler(tag); handler != nil {
|
||||||
log.Info("DefaultDispatcher: Taking detour [", tag, "] for [", destination, "].")
|
log.Info("DefaultDispatcher: Taking detour [", tag, "] for [", destination, "].")
|
||||||
dispatcher = handler
|
dispatcher = handler
|
||||||
} else {
|
} else {
|
||||||
|
@ -64,14 +64,14 @@ func (this *DefaultDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ra
|
||||||
if session.Inbound != nil && session.Inbound.AllowPassiveConnection {
|
if session.Inbound != nil && session.Inbound.AllowPassiveConnection {
|
||||||
go dispatcher.Dispatch(destination, alloc.NewLocalBuffer(32).Clear(), direct)
|
go dispatcher.Dispatch(destination, alloc.NewLocalBuffer(32).Clear(), direct)
|
||||||
} else {
|
} else {
|
||||||
go this.FilterPacketAndDispatch(destination, direct, dispatcher)
|
go v.FilterPacketAndDispatch(destination, direct, dispatcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
return direct
|
return direct
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private: Visible for testing.
|
// Private: Visible for testing.
|
||||||
func (this *DefaultDispatcher) FilterPacketAndDispatch(destination v2net.Destination, link ray.OutboundRay, dispatcher proxy.OutboundHandler) {
|
func (v *DefaultDispatcher) FilterPacketAndDispatch(destination v2net.Destination, link ray.OutboundRay, dispatcher proxy.OutboundHandler) {
|
||||||
payload, err := link.OutboundInput().Read()
|
payload, err := link.OutboundInput().Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("DefaultDispatcher: No payload towards ", destination, ", stopping now.")
|
log.Info("DefaultDispatcher: No payload towards ", destination, ", stopping now.")
|
||||||
|
|
|
@ -30,10 +30,10 @@ func NewTestPacketDispatcher(handler func(destination v2net.Destination, traffic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TestPacketDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay {
|
func (v *TestPacketDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay {
|
||||||
traffic := ray.NewRay()
|
traffic := ray.NewRay()
|
||||||
this.Destination <- session.Destination
|
v.Destination <- session.Destination
|
||||||
go this.Handler(session.Destination, traffic)
|
go v.Handler(session.Destination, traffic)
|
||||||
|
|
||||||
return traffic
|
return traffic
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,50 +58,50 @@ func NewUDPNameServer(address v2net.Destination, dispatcher dispatcher.PacketDis
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private: Visible for testing.
|
// Private: Visible for testing.
|
||||||
func (this *UDPNameServer) Cleanup() {
|
func (v *UDPNameServer) Cleanup() {
|
||||||
expiredRequests := make([]uint16, 0, 16)
|
expiredRequests := make([]uint16, 0, 16)
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
this.Lock()
|
v.Lock()
|
||||||
for id, r := range this.requests {
|
for id, r := range v.requests {
|
||||||
if r.expire.Before(now) {
|
if r.expire.Before(now) {
|
||||||
expiredRequests = append(expiredRequests, id)
|
expiredRequests = append(expiredRequests, id)
|
||||||
close(r.response)
|
close(r.response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, id := range expiredRequests {
|
for _, id := range expiredRequests {
|
||||||
delete(this.requests, id)
|
delete(v.requests, id)
|
||||||
}
|
}
|
||||||
this.Unlock()
|
v.Unlock()
|
||||||
expiredRequests = nil
|
expiredRequests = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private: Visible for testing.
|
// Private: Visible for testing.
|
||||||
func (this *UDPNameServer) AssignUnusedID(response chan<- *ARecord) uint16 {
|
func (v *UDPNameServer) AssignUnusedID(response chan<- *ARecord) uint16 {
|
||||||
var id uint16
|
var id uint16
|
||||||
this.Lock()
|
v.Lock()
|
||||||
if len(this.requests) > CleanupThreshold && this.nextCleanup.Before(time.Now()) {
|
if len(v.requests) > CleanupThreshold && v.nextCleanup.Before(time.Now()) {
|
||||||
this.nextCleanup = time.Now().Add(CleanupInterval)
|
v.nextCleanup = time.Now().Add(CleanupInterval)
|
||||||
go this.Cleanup()
|
go v.Cleanup()
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
id = uint16(dice.Roll(65536))
|
id = uint16(dice.Roll(65536))
|
||||||
if _, found := this.requests[id]; found {
|
if _, found := v.requests[id]; found {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Debug("DNS: Add pending request id ", id)
|
log.Debug("DNS: Add pending request id ", id)
|
||||||
this.requests[id] = &PendingRequest{
|
v.requests[id] = &PendingRequest{
|
||||||
expire: time.Now().Add(time.Second * 8),
|
expire: time.Now().Add(time.Second * 8),
|
||||||
response: response,
|
response: response,
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
this.Unlock()
|
v.Unlock()
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private: Visible for testing.
|
// Private: Visible for testing.
|
||||||
func (this *UDPNameServer) HandleResponse(dest v2net.Destination, payload *alloc.Buffer) {
|
func (v *UDPNameServer) HandleResponse(dest v2net.Destination, payload *alloc.Buffer) {
|
||||||
msg := new(dns.Msg)
|
msg := new(dns.Msg)
|
||||||
err := msg.Unpack(payload.Value)
|
err := msg.Unpack(payload.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -115,14 +115,14 @@ func (this *UDPNameServer) HandleResponse(dest v2net.Destination, payload *alloc
|
||||||
ttl := DefaultTTL
|
ttl := DefaultTTL
|
||||||
log.Debug("DNS: Handling response for id ", id, " content: ", msg.String())
|
log.Debug("DNS: Handling response for id ", id, " content: ", msg.String())
|
||||||
|
|
||||||
this.Lock()
|
v.Lock()
|
||||||
request, found := this.requests[id]
|
request, found := v.requests[id]
|
||||||
if !found {
|
if !found {
|
||||||
this.Unlock()
|
v.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
delete(this.requests, id)
|
delete(v.requests, id)
|
||||||
this.Unlock()
|
v.Unlock()
|
||||||
|
|
||||||
for _, rr := range msg.Answer {
|
for _, rr := range msg.Answer {
|
||||||
switch rr := rr.(type) {
|
switch rr := rr.(type) {
|
||||||
|
@ -144,7 +144,7 @@ func (this *UDPNameServer) HandleResponse(dest v2net.Destination, payload *alloc
|
||||||
close(request.response)
|
close(request.response)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *UDPNameServer) BuildQueryA(domain string, id uint16) *alloc.Buffer {
|
func (v *UDPNameServer) BuildQueryA(domain string, id uint16) *alloc.Buffer {
|
||||||
buffer := alloc.NewBuffer()
|
buffer := alloc.NewBuffer()
|
||||||
msg := new(dns.Msg)
|
msg := new(dns.Msg)
|
||||||
msg.Id = id
|
msg.Id = id
|
||||||
|
@ -162,24 +162,24 @@ func (this *UDPNameServer) BuildQueryA(domain string, id uint16) *alloc.Buffer {
|
||||||
return buffer
|
return buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *UDPNameServer) DispatchQuery(payload *alloc.Buffer) {
|
func (v *UDPNameServer) DispatchQuery(payload *alloc.Buffer) {
|
||||||
this.udpServer.Dispatch(&proxy.SessionInfo{Source: pseudoDestination, Destination: this.address}, payload, this.HandleResponse)
|
v.udpServer.Dispatch(&proxy.SessionInfo{Source: pseudoDestination, Destination: v.address}, payload, v.HandleResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *UDPNameServer) QueryA(domain string) <-chan *ARecord {
|
func (v *UDPNameServer) QueryA(domain string) <-chan *ARecord {
|
||||||
response := make(chan *ARecord, 1)
|
response := make(chan *ARecord, 1)
|
||||||
id := this.AssignUnusedID(response)
|
id := v.AssignUnusedID(response)
|
||||||
|
|
||||||
this.DispatchQuery(this.BuildQueryA(domain, id))
|
v.DispatchQuery(v.BuildQueryA(domain, id))
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
this.Lock()
|
v.Lock()
|
||||||
_, found := this.requests[id]
|
_, found := v.requests[id]
|
||||||
this.Unlock()
|
v.Unlock()
|
||||||
if found {
|
if found {
|
||||||
this.DispatchQuery(this.BuildQueryA(domain, id))
|
v.DispatchQuery(v.BuildQueryA(domain, id))
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,7 @@ func (this *UDPNameServer) QueryA(domain string) <-chan *ARecord {
|
||||||
type LocalNameServer struct {
|
type LocalNameServer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *LocalNameServer) QueryA(domain string) <-chan *ARecord {
|
func (v *LocalNameServer) QueryA(domain string) <-chan *ARecord {
|
||||||
response := make(chan *ARecord, 1)
|
response := make(chan *ARecord, 1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
|
|
@ -65,44 +65,44 @@ func NewCacheServer(space app.Space, config *Config) *CacheServer {
|
||||||
return server
|
return server
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *CacheServer) Release() {
|
func (v *CacheServer) Release() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private: Visible for testing.
|
// Private: Visible for testing.
|
||||||
func (this *CacheServer) GetCached(domain string) []net.IP {
|
func (v *CacheServer) GetCached(domain string) []net.IP {
|
||||||
this.RLock()
|
v.RLock()
|
||||||
defer this.RUnlock()
|
defer v.RUnlock()
|
||||||
|
|
||||||
if record, found := this.records[domain]; found && record.A.Expire.After(time.Now()) {
|
if record, found := v.records[domain]; found && record.A.Expire.After(time.Now()) {
|
||||||
return record.A.IPs
|
return record.A.IPs
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *CacheServer) Get(domain string) []net.IP {
|
func (v *CacheServer) Get(domain string) []net.IP {
|
||||||
if ip, found := this.hosts[domain]; found {
|
if ip, found := v.hosts[domain]; found {
|
||||||
return []net.IP{ip}
|
return []net.IP{ip}
|
||||||
}
|
}
|
||||||
|
|
||||||
domain = dns.Fqdn(domain)
|
domain = dns.Fqdn(domain)
|
||||||
ips := this.GetCached(domain)
|
ips := v.GetCached(domain)
|
||||||
if ips != nil {
|
if ips != nil {
|
||||||
return ips
|
return ips
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, server := range this.servers {
|
for _, server := range v.servers {
|
||||||
response := server.QueryA(domain)
|
response := server.QueryA(domain)
|
||||||
select {
|
select {
|
||||||
case a, open := <-response:
|
case a, open := <-response:
|
||||||
if !open || a == nil {
|
if !open || a == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
this.Lock()
|
v.Lock()
|
||||||
this.records[domain] = &DomainRecord{
|
v.records[domain] = &DomainRecord{
|
||||||
A: a,
|
A: a,
|
||||||
}
|
}
|
||||||
this.Unlock()
|
v.Unlock()
|
||||||
log.Debug("DNS: Returning ", len(a.IPs), " IPs for domain ", domain)
|
log.Debug("DNS: Returning ", len(a.IPs), " IPs for domain ", domain)
|
||||||
return a.IPs
|
return a.IPs
|
||||||
case <-time.After(QueryTimeout):
|
case <-time.After(QueryTimeout):
|
||||||
|
@ -115,12 +115,12 @@ func (this *CacheServer) Get(domain string) []net.IP {
|
||||||
|
|
||||||
type CacheServerFactory struct{}
|
type CacheServerFactory struct{}
|
||||||
|
|
||||||
func (this CacheServerFactory) Create(space app.Space, config interface{}) (app.Application, error) {
|
func (v CacheServerFactory) Create(space app.Space, config interface{}) (app.Application, error) {
|
||||||
server := NewCacheServer(space, config.(*Config))
|
server := NewCacheServer(space, config.(*Config))
|
||||||
return server, nil
|
return server, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this CacheServerFactory) AppId() app.ID {
|
func (v CacheServerFactory) AppId() app.ID {
|
||||||
return APP_ID
|
return APP_ID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,12 +35,12 @@ func NewOutboundProxy(space app.Space) *OutboundProxy {
|
||||||
return proxy
|
return proxy
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *OutboundProxy) RegisterDialer() {
|
func (v *OutboundProxy) RegisterDialer() {
|
||||||
internet.ProxyDialer = this.Dial
|
internet.ProxyDialer = v.Dial
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *OutboundProxy) Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) {
|
func (v *OutboundProxy) Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) {
|
||||||
handler := this.outboundManager.GetHandler(options.Proxy.Tag)
|
handler := v.outboundManager.GetHandler(options.Proxy.Tag)
|
||||||
if handler == nil {
|
if handler == nil {
|
||||||
log.Warning("Proxy: Failed to get outbound handler with tag: ", options.Proxy.Tag)
|
log.Warning("Proxy: Failed to get outbound handler with tag: ", options.Proxy.Tag)
|
||||||
return internet.Dial(src, dest, internet.DialerOptions{
|
return internet.Dial(src, dest, internet.DialerOptions{
|
||||||
|
@ -53,7 +53,7 @@ func (this *OutboundProxy) Dial(src v2net.Address, dest v2net.Destination, optio
|
||||||
return NewProxyConnection(src, dest, stream), nil
|
return NewProxyConnection(src, dest, stream), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *OutboundProxy) Release() {
|
func (v *OutboundProxy) Release() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,53 +83,53 @@ func NewProxyConnection(src v2net.Address, dest v2net.Destination, stream ray.Ra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ProxyConnection) Read(b []byte) (int, error) {
|
func (v *ProxyConnection) Read(b []byte) (int, error) {
|
||||||
if this.closed {
|
if v.closed {
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
return this.reader.Read(b)
|
return v.reader.Read(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ProxyConnection) Write(b []byte) (int, error) {
|
func (v *ProxyConnection) Write(b []byte) (int, error) {
|
||||||
if this.closed {
|
if v.closed {
|
||||||
return 0, io.ErrClosedPipe
|
return 0, io.ErrClosedPipe
|
||||||
}
|
}
|
||||||
return this.writer.Write(b)
|
return v.writer.Write(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ProxyConnection) Close() error {
|
func (v *ProxyConnection) Close() error {
|
||||||
this.closed = true
|
v.closed = true
|
||||||
this.stream.InboundInput().Close()
|
v.stream.InboundInput().Close()
|
||||||
this.stream.InboundOutput().Release()
|
v.stream.InboundOutput().Release()
|
||||||
this.reader.Release()
|
v.reader.Release()
|
||||||
this.writer.Release()
|
v.writer.Release()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ProxyConnection) LocalAddr() net.Addr {
|
func (v *ProxyConnection) LocalAddr() net.Addr {
|
||||||
return this.localAddr
|
return v.localAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ProxyConnection) RemoteAddr() net.Addr {
|
func (v *ProxyConnection) RemoteAddr() net.Addr {
|
||||||
return this.remoteAddr
|
return v.remoteAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ProxyConnection) SetDeadline(t time.Time) error {
|
func (v *ProxyConnection) SetDeadline(t time.Time) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ProxyConnection) SetReadDeadline(t time.Time) error {
|
func (v *ProxyConnection) SetReadDeadline(t time.Time) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ProxyConnection) SetWriteDeadline(t time.Time) error {
|
func (v *ProxyConnection) SetWriteDeadline(t time.Time) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ProxyConnection) Reusable() bool {
|
func (v *ProxyConnection) Reusable() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ProxyConnection) SetReusable(bool) {
|
func (v *ProxyConnection) SetReusable(bool) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,37 +33,37 @@ func NewDefaultOutboundHandlerManager() *DefaultOutboundHandlerManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DefaultOutboundHandlerManager) Release() {
|
func (v *DefaultOutboundHandlerManager) Release() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DefaultOutboundHandlerManager) GetDefaultHandler() proxy.OutboundHandler {
|
func (v *DefaultOutboundHandlerManager) GetDefaultHandler() proxy.OutboundHandler {
|
||||||
this.RLock()
|
v.RLock()
|
||||||
defer this.RUnlock()
|
defer v.RUnlock()
|
||||||
if this.defaultHandler == nil {
|
if v.defaultHandler == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return this.defaultHandler
|
return v.defaultHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DefaultOutboundHandlerManager) SetDefaultHandler(handler proxy.OutboundHandler) {
|
func (v *DefaultOutboundHandlerManager) SetDefaultHandler(handler proxy.OutboundHandler) {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
this.defaultHandler = handler
|
v.defaultHandler = handler
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DefaultOutboundHandlerManager) GetHandler(tag string) proxy.OutboundHandler {
|
func (v *DefaultOutboundHandlerManager) GetHandler(tag string) proxy.OutboundHandler {
|
||||||
this.RLock()
|
v.RLock()
|
||||||
defer this.RUnlock()
|
defer v.RUnlock()
|
||||||
if handler, found := this.taggedHandler[tag]; found {
|
if handler, found := v.taggedHandler[tag]; found {
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DefaultOutboundHandlerManager) SetHandler(tag string, handler proxy.OutboundHandler) {
|
func (v *DefaultOutboundHandlerManager) SetHandler(tag string, handler proxy.OutboundHandler) {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
this.taggedHandler[tag] = handler
|
v.taggedHandler[tag] = handler
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,13 +20,13 @@ func NewConditionChan() *ConditionChan {
|
||||||
return &condChan
|
return &condChan
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ConditionChan) Add(cond Condition) *ConditionChan {
|
func (v *ConditionChan) Add(cond Condition) *ConditionChan {
|
||||||
*this = append(*this, cond)
|
*v = append(*v, cond)
|
||||||
return this
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ConditionChan) Apply(session *proxy.SessionInfo) bool {
|
func (v *ConditionChan) Apply(session *proxy.SessionInfo) bool {
|
||||||
for _, cond := range *this {
|
for _, cond := range *v {
|
||||||
if !cond.Apply(session) {
|
if !cond.Apply(session) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,8 @@ func (this *ConditionChan) Apply(session *proxy.SessionInfo) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ConditionChan) Len() int {
|
func (v *ConditionChan) Len() int {
|
||||||
return len(*this)
|
return len(*v)
|
||||||
}
|
}
|
||||||
|
|
||||||
type AnyCondition []Condition
|
type AnyCondition []Condition
|
||||||
|
@ -45,13 +45,13 @@ func NewAnyCondition() *AnyCondition {
|
||||||
return &anyCond
|
return &anyCond
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AnyCondition) Add(cond Condition) *AnyCondition {
|
func (v *AnyCondition) Add(cond Condition) *AnyCondition {
|
||||||
*this = append(*this, cond)
|
*v = append(*v, cond)
|
||||||
return this
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AnyCondition) Apply(session *proxy.SessionInfo) bool {
|
func (v *AnyCondition) Apply(session *proxy.SessionInfo) bool {
|
||||||
for _, cond := range *this {
|
for _, cond := range *v {
|
||||||
if cond.Apply(session) {
|
if cond.Apply(session) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,8 @@ func (this *AnyCondition) Apply(session *proxy.SessionInfo) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AnyCondition) Len() int {
|
func (v *AnyCondition) Len() int {
|
||||||
return len(*this)
|
return len(*v)
|
||||||
}
|
}
|
||||||
|
|
||||||
type PlainDomainMatcher struct {
|
type PlainDomainMatcher struct {
|
||||||
|
@ -73,13 +73,13 @@ func NewPlainDomainMatcher(pattern string) *PlainDomainMatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *PlainDomainMatcher) Apply(session *proxy.SessionInfo) bool {
|
func (v *PlainDomainMatcher) Apply(session *proxy.SessionInfo) bool {
|
||||||
dest := session.Destination
|
dest := session.Destination
|
||||||
if !dest.Address.Family().IsDomain() {
|
if !dest.Address.Family().IsDomain() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
domain := dest.Address.Domain()
|
domain := dest.Address.Domain()
|
||||||
return strings.Contains(domain, this.pattern)
|
return strings.Contains(domain, v.pattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
type RegexpDomainMatcher struct {
|
type RegexpDomainMatcher struct {
|
||||||
|
@ -96,13 +96,13 @@ func NewRegexpDomainMatcher(pattern string) (*RegexpDomainMatcher, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RegexpDomainMatcher) Apply(session *proxy.SessionInfo) bool {
|
func (v *RegexpDomainMatcher) Apply(session *proxy.SessionInfo) bool {
|
||||||
dest := session.Destination
|
dest := session.Destination
|
||||||
if !dest.Address.Family().IsDomain() {
|
if !dest.Address.Family().IsDomain() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
domain := dest.Address.Domain()
|
domain := dest.Address.Domain()
|
||||||
return this.pattern.MatchString(strings.ToLower(domain))
|
return v.pattern.MatchString(strings.ToLower(domain))
|
||||||
}
|
}
|
||||||
|
|
||||||
type CIDRMatcher struct {
|
type CIDRMatcher struct {
|
||||||
|
@ -121,15 +121,15 @@ func NewCIDRMatcher(ip []byte, mask uint32, onSource bool) (*CIDRMatcher, error)
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *CIDRMatcher) Apply(session *proxy.SessionInfo) bool {
|
func (v *CIDRMatcher) Apply(session *proxy.SessionInfo) bool {
|
||||||
dest := session.Destination
|
dest := session.Destination
|
||||||
if this.onSource {
|
if v.onSource {
|
||||||
dest = session.Source
|
dest = session.Source
|
||||||
}
|
}
|
||||||
if !dest.Address.Family().Either(v2net.AddressFamilyIPv4, v2net.AddressFamilyIPv6) {
|
if !dest.Address.Family().Either(v2net.AddressFamilyIPv4, v2net.AddressFamilyIPv6) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return this.cidr.Contains(dest.Address.IP())
|
return v.cidr.Contains(dest.Address.IP())
|
||||||
}
|
}
|
||||||
|
|
||||||
type IPv4Matcher struct {
|
type IPv4Matcher struct {
|
||||||
|
@ -144,15 +144,15 @@ func NewIPv4Matcher(ipnet *v2net.IPNet, onSource bool) *IPv4Matcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *IPv4Matcher) Apply(session *proxy.SessionInfo) bool {
|
func (v *IPv4Matcher) Apply(session *proxy.SessionInfo) bool {
|
||||||
dest := session.Destination
|
dest := session.Destination
|
||||||
if this.onSource {
|
if v.onSource {
|
||||||
dest = session.Source
|
dest = session.Source
|
||||||
}
|
}
|
||||||
if !dest.Address.Family().Either(v2net.AddressFamilyIPv4) {
|
if !dest.Address.Family().Either(v2net.AddressFamilyIPv4) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return this.ipv4net.Contains(dest.Address.IP())
|
return v.ipv4net.Contains(dest.Address.IP())
|
||||||
}
|
}
|
||||||
|
|
||||||
type PortMatcher struct {
|
type PortMatcher struct {
|
||||||
|
@ -165,8 +165,8 @@ func NewPortMatcher(portRange v2net.PortRange) *PortMatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *PortMatcher) Apply(session *proxy.SessionInfo) bool {
|
func (v *PortMatcher) Apply(session *proxy.SessionInfo) bool {
|
||||||
return this.port.Contains(session.Destination.Port)
|
return v.port.Contains(session.Destination.Port)
|
||||||
}
|
}
|
||||||
|
|
||||||
type NetworkMatcher struct {
|
type NetworkMatcher struct {
|
||||||
|
@ -179,8 +179,8 @@ func NewNetworkMatcher(network *v2net.NetworkList) *NetworkMatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *NetworkMatcher) Apply(session *proxy.SessionInfo) bool {
|
func (v *NetworkMatcher) Apply(session *proxy.SessionInfo) bool {
|
||||||
return this.network.HasNetwork(session.Destination.Network)
|
return v.network.HasNetwork(session.Destination.Network)
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserMatcher struct {
|
type UserMatcher struct {
|
||||||
|
@ -193,11 +193,11 @@ func NewUserMatcher(users []string) *UserMatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *UserMatcher) Apply(session *proxy.SessionInfo) bool {
|
func (v *UserMatcher) Apply(session *proxy.SessionInfo) bool {
|
||||||
if session.User == nil {
|
if session.User == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for _, u := range this.user {
|
for _, u := range v.user {
|
||||||
if u == session.User.Email {
|
if u == session.User.Email {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -215,12 +215,12 @@ func NewInboundTagMatcher(tags []string) *InboundTagMatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundTagMatcher) Apply(session *proxy.SessionInfo) bool {
|
func (v *InboundTagMatcher) Apply(session *proxy.SessionInfo) bool {
|
||||||
if session.Inbound == nil || len(session.Inbound.Tag) == 0 {
|
if session.Inbound == nil || len(session.Inbound.Tag) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, t := range this.tags {
|
for _, t := range v.tags {
|
||||||
if t == session.Inbound.Tag {
|
if t == session.Inbound.Tag {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,16 @@ type Rule struct {
|
||||||
Condition Condition
|
Condition Condition
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Rule) Apply(session *proxy.SessionInfo) bool {
|
func (v *Rule) Apply(session *proxy.SessionInfo) bool {
|
||||||
return this.Condition.Apply(session)
|
return v.Condition.Apply(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RoutingRule) BuildCondition() (Condition, error) {
|
func (v *RoutingRule) BuildCondition() (Condition, error) {
|
||||||
conds := NewConditionChan()
|
conds := NewConditionChan()
|
||||||
|
|
||||||
if len(this.Domain) > 0 {
|
if len(v.Domain) > 0 {
|
||||||
anyCond := NewAnyCondition()
|
anyCond := NewAnyCondition()
|
||||||
for _, domain := range this.Domain {
|
for _, domain := range v.Domain {
|
||||||
if domain.Type == Domain_Plain {
|
if domain.Type == Domain_Plain {
|
||||||
anyCond.Add(NewPlainDomainMatcher(domain.Value))
|
anyCond.Add(NewPlainDomainMatcher(domain.Value))
|
||||||
} else {
|
} else {
|
||||||
|
@ -36,12 +36,12 @@ func (this *RoutingRule) BuildCondition() (Condition, error) {
|
||||||
conds.Add(anyCond)
|
conds.Add(anyCond)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(this.Cidr) > 0 {
|
if len(v.Cidr) > 0 {
|
||||||
ipv4Net := v2net.NewIPNet()
|
ipv4Net := v2net.NewIPNet()
|
||||||
ipv6Cond := NewAnyCondition()
|
ipv6Cond := NewAnyCondition()
|
||||||
hasIpv6 := false
|
hasIpv6 := false
|
||||||
|
|
||||||
for _, ip := range this.Cidr {
|
for _, ip := range v.Cidr {
|
||||||
switch len(ip.Ip) {
|
switch len(ip.Ip) {
|
||||||
case net.IPv4len:
|
case net.IPv4len:
|
||||||
ipv4Net.AddIP(ip.Ip, byte(ip.Prefix))
|
ipv4Net.AddIP(ip.Ip, byte(ip.Prefix))
|
||||||
|
@ -69,20 +69,20 @@ func (this *RoutingRule) BuildCondition() (Condition, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.PortRange != nil {
|
if v.PortRange != nil {
|
||||||
conds.Add(NewPortMatcher(*this.PortRange))
|
conds.Add(NewPortMatcher(*v.PortRange))
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.NetworkList != nil {
|
if v.NetworkList != nil {
|
||||||
conds.Add(NewNetworkMatcher(this.NetworkList))
|
conds.Add(NewNetworkMatcher(v.NetworkList))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(this.SourceCidr) > 0 {
|
if len(v.SourceCidr) > 0 {
|
||||||
ipv4Net := v2net.NewIPNet()
|
ipv4Net := v2net.NewIPNet()
|
||||||
ipv6Cond := NewAnyCondition()
|
ipv6Cond := NewAnyCondition()
|
||||||
hasIpv6 := false
|
hasIpv6 := false
|
||||||
|
|
||||||
for _, ip := range this.SourceCidr {
|
for _, ip := range v.SourceCidr {
|
||||||
switch len(ip.Ip) {
|
switch len(ip.Ip) {
|
||||||
case net.IPv4len:
|
case net.IPv4len:
|
||||||
ipv4Net.AddIP(ip.Ip, byte(ip.Prefix))
|
ipv4Net.AddIP(ip.Ip, byte(ip.Prefix))
|
||||||
|
@ -110,12 +110,12 @@ func (this *RoutingRule) BuildCondition() (Condition, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(this.UserEmail) > 0 {
|
if len(v.UserEmail) > 0 {
|
||||||
conds.Add(NewUserMatcher(this.UserEmail))
|
conds.Add(NewUserMatcher(v.UserEmail))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(this.InboundTag) > 0 {
|
if len(v.InboundTag) > 0 {
|
||||||
conds.Add(NewInboundTagMatcher(this.InboundTag))
|
conds.Add(NewInboundTagMatcher(v.InboundTag))
|
||||||
}
|
}
|
||||||
|
|
||||||
if conds.Len() == 0 {
|
if conds.Len() == 0 {
|
||||||
|
|
|
@ -53,13 +53,13 @@ func NewRouter(config *Config, space app.Space) *Router {
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Router) Release() {
|
func (v *Router) Release() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private: Visible for testing.
|
// Private: Visible for testing.
|
||||||
func (this *Router) ResolveIP(dest v2net.Destination) []v2net.Destination {
|
func (v *Router) ResolveIP(dest v2net.Destination) []v2net.Destination {
|
||||||
ips := this.dnsServer.Get(dest.Address.Domain())
|
ips := v.dnsServer.Get(dest.Address.Domain())
|
||||||
if len(ips) == 0 {
|
if len(ips) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -74,20 +74,20 @@ func (this *Router) ResolveIP(dest v2net.Destination) []v2net.Destination {
|
||||||
return dests
|
return dests
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Router) takeDetourWithoutCache(session *proxy.SessionInfo) (string, error) {
|
func (v *Router) takeDetourWithoutCache(session *proxy.SessionInfo) (string, error) {
|
||||||
for _, rule := range this.rules {
|
for _, rule := range v.rules {
|
||||||
if rule.Apply(session) {
|
if rule.Apply(session) {
|
||||||
return rule.Tag, nil
|
return rule.Tag, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dest := session.Destination
|
dest := session.Destination
|
||||||
if this.domainStrategy == Config_IpIfNonMatch && dest.Address.Family().IsDomain() {
|
if v.domainStrategy == Config_IpIfNonMatch && 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 := v.ResolveIP(dest)
|
||||||
if ipDests != nil {
|
if ipDests != nil {
|
||||||
for _, ipDest := range ipDests {
|
for _, ipDest := range ipDests {
|
||||||
log.Info("Router: Trying IP ", ipDest)
|
log.Info("Router: Trying IP ", ipDest)
|
||||||
for _, rule := range this.rules {
|
for _, rule := range v.rules {
|
||||||
if rule.Apply(&proxy.SessionInfo{
|
if rule.Apply(&proxy.SessionInfo{
|
||||||
Source: session.Source,
|
Source: session.Source,
|
||||||
Destination: ipDest,
|
Destination: ipDest,
|
||||||
|
@ -103,12 +103,12 @@ func (this *Router) takeDetourWithoutCache(session *proxy.SessionInfo) (string,
|
||||||
return "", ErrNoRuleApplicable
|
return "", ErrNoRuleApplicable
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Router) TakeDetour(session *proxy.SessionInfo) (string, error) {
|
func (v *Router) TakeDetour(session *proxy.SessionInfo) (string, error) {
|
||||||
//destStr := dest.String()
|
//destStr := dest.String()
|
||||||
//found, tag, err := this.cache.Get(destStr)
|
//found, tag, err := v.cache.Get(destStr)
|
||||||
//if !found {
|
//if !found {
|
||||||
tag, err := this.takeDetourWithoutCache(session)
|
tag, err := v.takeDetourWithoutCache(session)
|
||||||
//this.cache.Set(destStr, tag, err)
|
//v.cache.Set(destStr, tag, err)
|
||||||
return tag, err
|
return tag, err
|
||||||
//}
|
//}
|
||||||
//return tag, err
|
//return tag, err
|
||||||
|
|
|
@ -11,12 +11,12 @@ type RoutingEntry struct {
|
||||||
expire time.Time
|
expire time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RoutingEntry) Extend() {
|
func (v *RoutingEntry) Extend() {
|
||||||
this.expire = time.Now().Add(time.Hour)
|
v.expire = time.Now().Add(time.Hour)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RoutingEntry) Expired() bool {
|
func (v *RoutingEntry) Expired() bool {
|
||||||
return this.expire.Before(time.Now())
|
return v.expire.Before(time.Now())
|
||||||
}
|
}
|
||||||
|
|
||||||
type RoutingTable struct {
|
type RoutingTable struct {
|
||||||
|
@ -30,38 +30,38 @@ func NewRoutingTable() *RoutingTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RoutingTable) Cleanup() {
|
func (v *RoutingTable) Cleanup() {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
for key, value := range this.table {
|
for key, value := range v.table {
|
||||||
if value.Expired() {
|
if value.Expired() {
|
||||||
delete(this.table, key)
|
delete(v.table, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RoutingTable) Set(destination string, tag string, err error) {
|
func (v *RoutingTable) Set(destination string, tag string, err error) {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
entry := &RoutingEntry{
|
entry := &RoutingEntry{
|
||||||
tag: tag,
|
tag: tag,
|
||||||
err: err,
|
err: err,
|
||||||
}
|
}
|
||||||
entry.Extend()
|
entry.Extend()
|
||||||
this.table[destination] = entry
|
v.table[destination] = entry
|
||||||
|
|
||||||
if len(this.table) > 1000 {
|
if len(v.table) > 1000 {
|
||||||
go this.Cleanup()
|
go v.Cleanup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RoutingTable) Get(destination string) (bool, string, error) {
|
func (v *RoutingTable) Get(destination string) (bool, string, error) {
|
||||||
this.RLock()
|
v.RLock()
|
||||||
defer this.RUnlock()
|
defer v.RUnlock()
|
||||||
|
|
||||||
entry, found := this.table[destination]
|
entry, found := v.table[destination]
|
||||||
if !found {
|
if !found {
|
||||||
return false, "", nil
|
return false, "", nil
|
||||||
}
|
}
|
||||||
|
|
26
app/space.go
26
app/space.go
|
@ -60,12 +60,12 @@ func NewSpace() Space {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *spaceImpl) InitializeApplication(f ApplicationInitializer) {
|
func (v *spaceImpl) InitializeApplication(f ApplicationInitializer) {
|
||||||
this.appInit = append(this.appInit, f)
|
v.appInit = append(v.appInit, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *spaceImpl) Initialize() error {
|
func (v *spaceImpl) Initialize() error {
|
||||||
for _, f := range this.appInit {
|
for _, f := range v.appInit {
|
||||||
err := f()
|
err := f()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -74,32 +74,32 @@ func (this *spaceImpl) Initialize() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *spaceImpl) HasApp(id ID) bool {
|
func (v *spaceImpl) HasApp(id ID) bool {
|
||||||
_, found := this.cache[id]
|
_, found := v.cache[id]
|
||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *spaceImpl) GetApp(id ID) Application {
|
func (v *spaceImpl) GetApp(id ID) Application {
|
||||||
obj, found := this.cache[id]
|
obj, found := v.cache[id]
|
||||||
if !found {
|
if !found {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *spaceImpl) BindApp(id ID, application Application) {
|
func (v *spaceImpl) BindApp(id ID, application Application) {
|
||||||
this.cache[id] = application
|
v.cache[id] = application
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *spaceImpl) BindFromConfig(name string, config interface{}) error {
|
func (v *spaceImpl) BindFromConfig(name string, config interface{}) error {
|
||||||
factory, found := applicationFactoryCache[name]
|
factory, found := applicationFactoryCache[name]
|
||||||
if !found {
|
if !found {
|
||||||
return errors.New("Space: app not registered: " + name)
|
return errors.New("Space: app not registered: " + name)
|
||||||
}
|
}
|
||||||
app, err := factory.Create(this, config)
|
app, err := factory.Create(v, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.BindApp(factory.AppId(), app)
|
v.BindApp(factory.AppId(), app)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,20 +19,20 @@ func NewCryptionReader(stream cipher.Stream, reader io.Reader) *CryptionReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *CryptionReader) Read(data []byte) (int, error) {
|
func (v *CryptionReader) Read(data []byte) (int, error) {
|
||||||
if this.reader == nil {
|
if v.reader == nil {
|
||||||
return 0, common.ErrObjectReleased
|
return 0, common.ErrObjectReleased
|
||||||
}
|
}
|
||||||
nBytes, err := this.reader.Read(data)
|
nBytes, err := v.reader.Read(data)
|
||||||
if nBytes > 0 {
|
if nBytes > 0 {
|
||||||
this.stream.XORKeyStream(data[:nBytes], data[:nBytes])
|
v.stream.XORKeyStream(data[:nBytes], data[:nBytes])
|
||||||
}
|
}
|
||||||
return nBytes, err
|
return nBytes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *CryptionReader) Release() {
|
func (v *CryptionReader) Release() {
|
||||||
this.reader = nil
|
v.reader = nil
|
||||||
this.stream = nil
|
v.stream = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type CryptionWriter struct {
|
type CryptionWriter struct {
|
||||||
|
@ -47,15 +47,15 @@ func NewCryptionWriter(stream cipher.Stream, writer io.Writer) *CryptionWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *CryptionWriter) Write(data []byte) (int, error) {
|
func (v *CryptionWriter) Write(data []byte) (int, error) {
|
||||||
if this.writer == nil {
|
if v.writer == nil {
|
||||||
return 0, common.ErrObjectReleased
|
return 0, common.ErrObjectReleased
|
||||||
}
|
}
|
||||||
this.stream.XORKeyStream(data, data)
|
v.stream.XORKeyStream(data, data)
|
||||||
return this.writer.Write(data)
|
return v.writer.Write(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *CryptionWriter) Release() {
|
func (v *CryptionWriter) Release() {
|
||||||
this.writer = nil
|
v.writer = nil
|
||||||
this.stream = nil
|
v.stream = nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,47 +22,47 @@ func NewBufferedReader(rawReader io.Reader) *BufferedReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *BufferedReader) Release() {
|
func (v *BufferedReader) Release() {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
this.buffer.Release()
|
v.buffer.Release()
|
||||||
this.buffer = nil
|
v.buffer = nil
|
||||||
this.reader = nil
|
v.reader = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *BufferedReader) Cached() bool {
|
func (v *BufferedReader) Cached() bool {
|
||||||
return this.cached
|
return v.cached
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *BufferedReader) SetCached(cached bool) {
|
func (v *BufferedReader) SetCached(cached bool) {
|
||||||
this.cached = cached
|
v.cached = cached
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *BufferedReader) Read(b []byte) (int, error) {
|
func (v *BufferedReader) Read(b []byte) (int, error) {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
if this.reader == nil {
|
if v.reader == nil {
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
if !this.cached {
|
if !v.cached {
|
||||||
if !this.buffer.IsEmpty() {
|
if !v.buffer.IsEmpty() {
|
||||||
return this.buffer.Read(b)
|
return v.buffer.Read(b)
|
||||||
}
|
}
|
||||||
return this.reader.Read(b)
|
return v.reader.Read(b)
|
||||||
}
|
}
|
||||||
if this.buffer.IsEmpty() {
|
if v.buffer.IsEmpty() {
|
||||||
_, err := this.buffer.FillFrom(this.reader)
|
_, err := v.buffer.FillFrom(v.reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.buffer.IsEmpty() {
|
if v.buffer.IsEmpty() {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.buffer.Read(b)
|
return v.buffer.Read(b)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,17 +21,17 @@ func NewBufferedWriter(rawWriter io.Writer) *BufferedWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *BufferedWriter) ReadFrom(reader io.Reader) (int64, error) {
|
func (v *BufferedWriter) ReadFrom(reader io.Reader) (int64, error) {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
if this.writer == nil {
|
if v.writer == nil {
|
||||||
return 0, io.ErrClosedPipe
|
return 0, io.ErrClosedPipe
|
||||||
}
|
}
|
||||||
|
|
||||||
totalBytes := int64(0)
|
totalBytes := int64(0)
|
||||||
for {
|
for {
|
||||||
nBytes, err := this.buffer.FillFrom(reader)
|
nBytes, err := v.buffer.FillFrom(reader)
|
||||||
totalBytes += int64(nBytes)
|
totalBytes += int64(nBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
|
@ -39,69 +39,69 @@ func (this *BufferedWriter) ReadFrom(reader io.Reader) (int64, error) {
|
||||||
}
|
}
|
||||||
return totalBytes, err
|
return totalBytes, err
|
||||||
}
|
}
|
||||||
this.FlushWithoutLock()
|
v.FlushWithoutLock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *BufferedWriter) Write(b []byte) (int, error) {
|
func (v *BufferedWriter) Write(b []byte) (int, error) {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
if this.writer == nil {
|
if v.writer == nil {
|
||||||
return 0, io.ErrClosedPipe
|
return 0, io.ErrClosedPipe
|
||||||
}
|
}
|
||||||
|
|
||||||
if !this.cached {
|
if !v.cached {
|
||||||
return this.writer.Write(b)
|
return v.writer.Write(b)
|
||||||
}
|
}
|
||||||
nBytes, _ := this.buffer.Write(b)
|
nBytes, _ := v.buffer.Write(b)
|
||||||
if this.buffer.IsFull() {
|
if v.buffer.IsFull() {
|
||||||
this.FlushWithoutLock()
|
v.FlushWithoutLock()
|
||||||
}
|
}
|
||||||
return nBytes, nil
|
return nBytes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *BufferedWriter) Flush() error {
|
func (v *BufferedWriter) Flush() error {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
if this.writer == nil {
|
if v.writer == nil {
|
||||||
return io.ErrClosedPipe
|
return io.ErrClosedPipe
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.FlushWithoutLock()
|
return v.FlushWithoutLock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *BufferedWriter) FlushWithoutLock() error {
|
func (v *BufferedWriter) FlushWithoutLock() error {
|
||||||
defer this.buffer.Clear()
|
defer v.buffer.Clear()
|
||||||
for !this.buffer.IsEmpty() {
|
for !v.buffer.IsEmpty() {
|
||||||
nBytes, err := this.writer.Write(this.buffer.Value)
|
nBytes, err := v.writer.Write(v.buffer.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.buffer.SliceFrom(nBytes)
|
v.buffer.SliceFrom(nBytes)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *BufferedWriter) Cached() bool {
|
func (v *BufferedWriter) Cached() bool {
|
||||||
return this.cached
|
return v.cached
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *BufferedWriter) SetCached(cached bool) {
|
func (v *BufferedWriter) SetCached(cached bool) {
|
||||||
this.cached = cached
|
v.cached = cached
|
||||||
if !cached && !this.buffer.IsEmpty() {
|
if !cached && !v.buffer.IsEmpty() {
|
||||||
this.Flush()
|
v.Flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *BufferedWriter) Release() {
|
func (v *BufferedWriter) Release() {
|
||||||
this.Flush()
|
v.Flush()
|
||||||
|
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
this.buffer.Release()
|
v.buffer.Release()
|
||||||
this.buffer = nil
|
v.buffer = nil
|
||||||
this.writer = nil
|
v.writer = nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,10 @@ func NewChainWriter(writer Writer) *ChainWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ChainWriter) Write(payload []byte) (int, error) {
|
func (v *ChainWriter) Write(payload []byte) (int, error) {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
if this.writer == nil {
|
if v.writer == nil {
|
||||||
return 0, io.ErrClosedPipe
|
return 0, io.ErrClosedPipe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ func (this *ChainWriter) Write(payload []byte) (int, error) {
|
||||||
bytesWritten += size
|
bytesWritten += size
|
||||||
size = 0
|
size = 0
|
||||||
}
|
}
|
||||||
err := this.writer.Write(buffer)
|
err := v.writer.Write(buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return bytesWritten, err
|
return bytesWritten, err
|
||||||
}
|
}
|
||||||
|
@ -48,9 +48,9 @@ func (this *ChainWriter) Write(payload []byte) (int, error) {
|
||||||
return bytesWritten, nil
|
return bytesWritten, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ChainWriter) Release() {
|
func (v *ChainWriter) Release() {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
this.writer.Release()
|
v.writer.Release()
|
||||||
this.writer = nil
|
v.writer = nil
|
||||||
this.Unlock()
|
v.Unlock()
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,42 +21,42 @@ func NewChanReader(stream Reader) *ChanReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private: Visible for testing.
|
// Private: Visible for testing.
|
||||||
func (this *ChanReader) Fill() {
|
func (v *ChanReader) Fill() {
|
||||||
b, err := this.stream.Read()
|
b, err := v.stream.Read()
|
||||||
this.current = b
|
v.current = b
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.eof = true
|
v.eof = true
|
||||||
this.current = nil
|
v.current = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ChanReader) Read(b []byte) (int, error) {
|
func (v *ChanReader) Read(b []byte) (int, error) {
|
||||||
if this.eof {
|
if v.eof {
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
if this.current == nil {
|
if v.current == nil {
|
||||||
this.Fill()
|
v.Fill()
|
||||||
if this.eof {
|
if v.eof {
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nBytes, err := this.current.Read(b)
|
nBytes, err := v.current.Read(b)
|
||||||
if this.current.IsEmpty() {
|
if v.current.IsEmpty() {
|
||||||
this.current.Release()
|
v.current.Release()
|
||||||
this.current = nil
|
v.current = nil
|
||||||
}
|
}
|
||||||
return nBytes, err
|
return nBytes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ChanReader) Release() {
|
func (v *ChanReader) Release() {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
this.eof = true
|
v.eof = true
|
||||||
this.current.Release()
|
v.current.Release()
|
||||||
this.current = nil
|
v.current = nil
|
||||||
this.stream = nil
|
v.stream = nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,9 @@ func NewAdaptiveReader(reader io.Reader) *AdaptiveReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read implements Reader.Read().
|
// Read implements Reader.Read().
|
||||||
func (this *AdaptiveReader) Read() (*alloc.Buffer, error) {
|
func (v *AdaptiveReader) Read() (*alloc.Buffer, error) {
|
||||||
buffer := this.allocate().Clear()
|
buffer := v.allocate().Clear()
|
||||||
_, err := buffer.FillFrom(this.reader)
|
_, err := buffer.FillFrom(v.reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -41,6 +41,6 @@ func (this *AdaptiveReader) Read() (*alloc.Buffer, error) {
|
||||||
return buffer, nil
|
return buffer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AdaptiveReader) Release() {
|
func (v *AdaptiveReader) Release() {
|
||||||
this.reader = nil
|
v.reader = nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,10 @@ func NewAdaptiveWriter(writer io.Writer) *AdaptiveWriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write implements Writer.Write(). Write() takes ownership of the given buffer.
|
// Write implements Writer.Write(). Write() takes ownership of the given buffer.
|
||||||
func (this *AdaptiveWriter) Write(buffer *alloc.Buffer) error {
|
func (v *AdaptiveWriter) Write(buffer *alloc.Buffer) error {
|
||||||
defer buffer.Release()
|
defer buffer.Release()
|
||||||
for !buffer.IsEmpty() {
|
for !buffer.IsEmpty() {
|
||||||
nBytes, err := this.writer.Write(buffer.Value)
|
nBytes, err := v.writer.Write(buffer.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,6 @@ func (this *AdaptiveWriter) Write(buffer *alloc.Buffer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AdaptiveWriter) Release() {
|
func (v *AdaptiveWriter) Release() {
|
||||||
this.writer = nil
|
v.writer = nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,20 +30,20 @@ func GetInstance(messageType string) (interface{}, error) {
|
||||||
return reflect.New(mType).Interface(), nil
|
return reflect.New(mType).Interface(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TypedSettings) Load(message proto.Message) error {
|
func (v *TypedSettings) Load(message proto.Message) error {
|
||||||
targetType := GetType(message)
|
targetType := GetType(message)
|
||||||
if targetType != this.Type {
|
if targetType != v.Type {
|
||||||
return errors.New("Have type " + this.Type + ", but retrieved for " + targetType)
|
return errors.New("Have type " + v.Type + ", but retrieved for " + targetType)
|
||||||
}
|
}
|
||||||
return proto.Unmarshal(this.Settings, message)
|
return proto.Unmarshal(v.Settings, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TypedSettings) GetInstance() (interface{}, error) {
|
func (v *TypedSettings) GetInstance() (interface{}, error) {
|
||||||
instance, err := GetInstance(this.Type)
|
instance, err := GetInstance(v.Type)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := proto.Unmarshal(this.Settings, instance.(proto.Message)); err != nil {
|
if err := proto.Unmarshal(v.Settings, instance.(proto.Message)); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return instance, nil
|
return instance, nil
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
package log
|
package log
|
||||||
|
|
||||||
func (this *Config) Apply() error {
|
func (v *Config) Apply() error {
|
||||||
if this == nil {
|
if v == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if this.AccessLogType == LogType_File {
|
if v.AccessLogType == LogType_File {
|
||||||
if err := InitAccessLogger(this.AccessLogPath); err != nil {
|
if err := InitAccessLogger(v.AccessLogPath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.ErrorLogType == LogType_None {
|
if v.ErrorLogType == LogType_None {
|
||||||
SetLogLevel(LogLevel_Disabled)
|
SetLogLevel(LogLevel_Disabled)
|
||||||
} else {
|
} else {
|
||||||
if this.ErrorLogType == LogType_File {
|
if v.ErrorLogType == LogType_File {
|
||||||
if err := InitErrorLogger(this.ErrorLogPath); err != nil {
|
if err := InitErrorLogger(v.ErrorLogPath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetLogLevel(this.ErrorLogLevel)
|
SetLogLevel(v.ErrorLogLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -38,17 +38,17 @@ type ErrorLog struct {
|
||||||
Values []interface{}
|
Values []interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ErrorLog) Release() {
|
func (v *ErrorLog) Release() {
|
||||||
for index := range this.Values {
|
for index := range v.Values {
|
||||||
this.Values[index] = nil
|
v.Values[index] = nil
|
||||||
}
|
}
|
||||||
this.Values = nil
|
v.Values = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ErrorLog) String() string {
|
func (v *ErrorLog) String() string {
|
||||||
values := make([]string, len(this.Values)+1)
|
values := make([]string, len(v.Values)+1)
|
||||||
values[0] = this.Prefix
|
values[0] = v.Prefix
|
||||||
for i, value := range this.Values {
|
for i, value := range v.Values {
|
||||||
values[i+1] = InterfaceToString(value)
|
values[i+1] = InterfaceToString(value)
|
||||||
}
|
}
|
||||||
return strings.Join(values, "")
|
return strings.Join(values, "")
|
||||||
|
@ -61,12 +61,12 @@ type AccessLog struct {
|
||||||
Reason interface{}
|
Reason interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AccessLog) Release() {
|
func (v *AccessLog) Release() {
|
||||||
this.From = nil
|
v.From = nil
|
||||||
this.To = nil
|
v.To = nil
|
||||||
this.Reason = nil
|
v.Reason = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AccessLog) String() string {
|
func (v *AccessLog) String() string {
|
||||||
return strings.Join([]string{InterfaceToString(this.From), this.Status, InterfaceToString(this.To), InterfaceToString(this.Reason)}, " ")
|
return strings.Join([]string{InterfaceToString(v.From), v.Status, InterfaceToString(v.To), InterfaceToString(v.Reason)}, " ")
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,11 @@ type LogWriter interface {
|
||||||
type NoOpLogWriter struct {
|
type NoOpLogWriter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *NoOpLogWriter) Log(entry LogEntry) {
|
func (v *NoOpLogWriter) Log(entry LogEntry) {
|
||||||
entry.Release()
|
entry.Release()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *NoOpLogWriter) Close() {
|
func (v *NoOpLogWriter) Close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
type StdOutLogWriter struct {
|
type StdOutLogWriter struct {
|
||||||
|
@ -36,12 +36,12 @@ func NewStdOutLogWriter() LogWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *StdOutLogWriter) Log(log LogEntry) {
|
func (v *StdOutLogWriter) Log(log LogEntry) {
|
||||||
this.logger.Print(log.String() + platform.LineSeparator())
|
v.logger.Print(log.String() + platform.LineSeparator())
|
||||||
log.Release()
|
log.Release()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *StdOutLogWriter) Close() {
|
func (v *StdOutLogWriter) Close() {
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,32 +52,32 @@ type FileLogWriter struct {
|
||||||
cancel *signal.CancelSignal
|
cancel *signal.CancelSignal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *FileLogWriter) Log(log LogEntry) {
|
func (v *FileLogWriter) Log(log LogEntry) {
|
||||||
select {
|
select {
|
||||||
case this.queue <- log.String():
|
case v.queue <- log.String():
|
||||||
default:
|
default:
|
||||||
// We don't expect this to happen, but don't want to block main thread as well.
|
// We don't expect this to happen, but don't want to block main thread as well.
|
||||||
}
|
}
|
||||||
log.Release()
|
log.Release()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *FileLogWriter) run() {
|
func (v *FileLogWriter) run() {
|
||||||
this.cancel.WaitThread()
|
v.cancel.WaitThread()
|
||||||
defer this.cancel.FinishThread()
|
defer v.cancel.FinishThread()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
entry, open := <-this.queue
|
entry, open := <-v.queue
|
||||||
if !open {
|
if !open {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
this.logger.Print(entry + platform.LineSeparator())
|
v.logger.Print(entry + platform.LineSeparator())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *FileLogWriter) Close() {
|
func (v *FileLogWriter) Close() {
|
||||||
close(this.queue)
|
close(v.queue)
|
||||||
this.cancel.WaitForDone()
|
v.cancel.WaitForDone()
|
||||||
this.file.Close()
|
v.file.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFileLogWriter(path string) (*FileLogWriter, error) {
|
func NewFileLogWriter(path string) (*FileLogWriter, error) {
|
||||||
|
|
|
@ -20,25 +20,25 @@ const (
|
||||||
AddressFamilyDomain = AddressFamily(2)
|
AddressFamilyDomain = AddressFamily(2)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this AddressFamily) Either(fs ...AddressFamily) bool {
|
func (v AddressFamily) Either(fs ...AddressFamily) bool {
|
||||||
for _, f := range fs {
|
for _, f := range fs {
|
||||||
if this == f {
|
if v == f {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this AddressFamily) IsIPv4() bool {
|
func (v AddressFamily) IsIPv4() bool {
|
||||||
return this == AddressFamilyIPv4
|
return v == AddressFamilyIPv4
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this AddressFamily) IsIPv6() bool {
|
func (v AddressFamily) IsIPv6() bool {
|
||||||
return this == AddressFamilyIPv6
|
return v == AddressFamilyIPv6
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this AddressFamily) IsDomain() bool {
|
func (v AddressFamily) IsDomain() bool {
|
||||||
return this == AddressFamilyDomain
|
return v == 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
|
||||||
|
@ -104,8 +104,8 @@ func (addr ipv4Address) Family() AddressFamily {
|
||||||
return AddressFamilyIPv4
|
return AddressFamilyIPv4
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this ipv4Address) String() string {
|
func (v ipv4Address) String() string {
|
||||||
return this.IP().String()
|
return v.IP().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
type ipv6Address [16]byte
|
type ipv6Address [16]byte
|
||||||
|
@ -118,12 +118,12 @@ func (addr ipv6Address) Domain() string {
|
||||||
panic("Calling Domain() on an IPv6Address.")
|
panic("Calling Domain() on an IPv6Address.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this ipv6Address) Family() AddressFamily {
|
func (v ipv6Address) Family() AddressFamily {
|
||||||
return AddressFamilyIPv6
|
return AddressFamilyIPv6
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this ipv6Address) String() string {
|
func (v ipv6Address) String() string {
|
||||||
return "[" + this.IP().String() + "]"
|
return "[" + v.IP().String() + "]"
|
||||||
}
|
}
|
||||||
|
|
||||||
type domainAddress string
|
type domainAddress string
|
||||||
|
@ -140,15 +140,15 @@ func (addr domainAddress) Family() AddressFamily {
|
||||||
return AddressFamilyDomain
|
return AddressFamilyDomain
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this domainAddress) String() string {
|
func (v domainAddress) String() string {
|
||||||
return this.Domain()
|
return v.Domain()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *IPOrDomain) AsAddress() Address {
|
func (v *IPOrDomain) AsAddress() Address {
|
||||||
if this == nil {
|
if v == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
switch addr := this.Address.(type) {
|
switch addr := v.Address.(type) {
|
||||||
case *IPOrDomain_Ip:
|
case *IPOrDomain_Ip:
|
||||||
return IPAddress(addr.Ip)
|
return IPAddress(addr.Ip)
|
||||||
case *IPOrDomain_Domain:
|
case *IPOrDomain_Domain:
|
||||||
|
|
|
@ -40,18 +40,18 @@ func UDPDestination(address Address, port Port) Destination {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this Destination) NetAddr() string {
|
func (v Destination) NetAddr() string {
|
||||||
return this.Address.String() + ":" + this.Port.String()
|
return v.Address.String() + ":" + v.Port.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this Destination) String() string {
|
func (v Destination) String() string {
|
||||||
return this.Network.UrlPrefix() + ":" + this.NetAddr()
|
return v.Network.UrlPrefix() + ":" + v.NetAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Endpoint) AsDestination() Destination {
|
func (v *Endpoint) AsDestination() Destination {
|
||||||
return Destination{
|
return Destination{
|
||||||
Network: this.Network,
|
Network: v.Network,
|
||||||
Address: this.Address.AsAddress(),
|
Address: v.Address.AsAddress(),
|
||||||
Port: Port(this.Port),
|
Port: Port(v.Port),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,32 +35,32 @@ func ipMaskToByte(mask net.IPMask) byte {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *IPNet) Add(ipNet *net.IPNet) {
|
func (v *IPNet) Add(ipNet *net.IPNet) {
|
||||||
ipv4 := ipNet.IP.To4()
|
ipv4 := ipNet.IP.To4()
|
||||||
if ipv4 == nil {
|
if ipv4 == nil {
|
||||||
// For now, we don't support IPv6
|
// For now, we don't support IPv6
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mask := ipMaskToByte(ipNet.Mask)
|
mask := ipMaskToByte(ipNet.Mask)
|
||||||
this.AddIP(ipv4, mask)
|
v.AddIP(ipv4, mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *IPNet) AddIP(ip []byte, mask byte) {
|
func (v *IPNet) AddIP(ip []byte, mask byte) {
|
||||||
k := ipToUint32(ip)
|
k := ipToUint32(ip)
|
||||||
existing, found := this.cache[k]
|
existing, found := v.cache[k]
|
||||||
if !found || existing > mask {
|
if !found || existing > mask {
|
||||||
this.cache[k] = mask
|
v.cache[k] = mask
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *IPNet) Contains(ip net.IP) bool {
|
func (v *IPNet) Contains(ip net.IP) bool {
|
||||||
ipv4 := ip.To4()
|
ipv4 := ip.To4()
|
||||||
if ipv4 == nil {
|
if ipv4 == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
originalValue := ipToUint32(ipv4)
|
originalValue := ipToUint32(ipv4)
|
||||||
|
|
||||||
if entry, found := this.cache[originalValue]; found {
|
if entry, found := v.cache[originalValue]; found {
|
||||||
if entry == 32 {
|
if entry == 32 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ func (this *IPNet) Contains(ip net.IP) bool {
|
||||||
mask += 1 << uint32(32-maskbit)
|
mask += 1 << uint32(32-maskbit)
|
||||||
|
|
||||||
maskedValue := originalValue & mask
|
maskedValue := originalValue & mask
|
||||||
if entry, found := this.cache[maskedValue]; found {
|
if entry, found := v.cache[maskedValue]; found {
|
||||||
if entry == maskbit {
|
if entry == maskbit {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -80,8 +80,8 @@ func (this *IPNet) Contains(ip net.IP) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *IPNet) IsEmpty() bool {
|
func (v *IPNet) IsEmpty() bool {
|
||||||
return len(this.cache) == 0
|
return len(v.cache) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -22,14 +22,14 @@ func ParseNetwork(nwStr string) Network {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this Network) AsList() *NetworkList {
|
func (v Network) AsList() *NetworkList {
|
||||||
return &NetworkList{
|
return &NetworkList{
|
||||||
Network: []Network{this},
|
Network: []Network{v},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this Network) SystemString() string {
|
func (v Network) SystemString() string {
|
||||||
switch this {
|
switch v {
|
||||||
case Network_TCP, Network_RawTCP:
|
case Network_TCP, Network_RawTCP:
|
||||||
return "tcp"
|
return "tcp"
|
||||||
case Network_UDP, Network_KCP:
|
case Network_UDP, Network_KCP:
|
||||||
|
@ -39,8 +39,8 @@ func (this Network) SystemString() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this Network) UrlPrefix() string {
|
func (v Network) UrlPrefix() string {
|
||||||
switch this {
|
switch v {
|
||||||
case Network_TCP, Network_RawTCP:
|
case Network_TCP, Network_RawTCP:
|
||||||
return "tcp"
|
return "tcp"
|
||||||
case Network_UDP:
|
case Network_UDP:
|
||||||
|
@ -54,9 +54,9 @@ func (this Network) UrlPrefix() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HashNetwork returns true if the given network is in this NetworkList.
|
// HashNetwork returns true if the given network is in v NetworkList.
|
||||||
func (this NetworkList) HasNetwork(network Network) bool {
|
func (v NetworkList) HasNetwork(network Network) bool {
|
||||||
for _, value := range this.Network {
|
for _, value := range v.Network {
|
||||||
if string(value) == string(network) {
|
if string(value) == string(network) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,6 @@ func (this NetworkList) HasNetwork(network Network) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this NetworkList) Get(idx int) Network {
|
func (v NetworkList) Get(idx int) Network {
|
||||||
return this.Network[idx]
|
return v.Network[idx]
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,30 +40,30 @@ func PortFromString(s string) (Port, error) {
|
||||||
return PortFromInt(uint32(val))
|
return PortFromInt(uint32(val))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value return the correspoding uint16 value of this Port.
|
// Value return the correspoding uint16 value of v Port.
|
||||||
func (this Port) Value() uint16 {
|
func (v Port) Value() uint16 {
|
||||||
return uint16(this)
|
return uint16(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns the correspoding bytes of this Port, in big endian order.
|
// Bytes returns the correspoding bytes of v Port, in big endian order.
|
||||||
func (this Port) Bytes(b []byte) []byte {
|
func (v Port) Bytes(b []byte) []byte {
|
||||||
return serial.Uint16ToBytes(this.Value(), b)
|
return serial.Uint16ToBytes(v.Value(), b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the string presentation of this Port.
|
// String returns the string presentation of v Port.
|
||||||
func (this Port) String() string {
|
func (v Port) String() string {
|
||||||
return serial.Uint16ToString(this.Value())
|
return serial.Uint16ToString(v.Value())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this PortRange) FromPort() Port {
|
func (v PortRange) FromPort() Port {
|
||||||
return Port(this.From)
|
return Port(v.From)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this PortRange) ToPort() Port {
|
func (v PortRange) ToPort() Port {
|
||||||
return Port(this.To)
|
return Port(v.To)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contains returns true if the given port is within the range of this PortRange.
|
// Contains returns true if the given port is within the range of v PortRange.
|
||||||
func (this PortRange) Contains(port Port) bool {
|
func (v PortRange) Contains(port Port) bool {
|
||||||
return this.FromPort() <= port && port <= this.ToPort()
|
return v.FromPort() <= port && port <= v.ToPort()
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,11 +60,11 @@ type timedReaderWorker struct {
|
||||||
connection net.Conn
|
connection net.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *timedReaderWorker) Read(p []byte) (int, error) {
|
func (v *timedReaderWorker) Read(p []byte) (int, error) {
|
||||||
deadline := time.Duration(this.timeout) * time.Second
|
deadline := time.Duration(v.timeout) * time.Second
|
||||||
this.connection.SetReadDeadline(time.Now().Add(deadline))
|
v.connection.SetReadDeadline(time.Now().Add(deadline))
|
||||||
nBytes, err := this.connection.Read(p)
|
nBytes, err := v.connection.Read(p)
|
||||||
this.connection.SetReadDeadline(emptyTime)
|
v.connection.SetReadDeadline(emptyTime)
|
||||||
return nBytes, err
|
return nBytes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,6 @@ type noOpReaderWorker struct {
|
||||||
connection net.Conn
|
connection net.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *noOpReaderWorker) Read(p []byte) (int, error) {
|
func (v *noOpReaderWorker) Read(p []byte) (int, error) {
|
||||||
return this.connection.Read(p)
|
return v.connection.Read(p)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,12 @@ package predicate
|
||||||
|
|
||||||
type Predicate func() bool
|
type Predicate func() bool
|
||||||
|
|
||||||
func (this Predicate) And(predicate Predicate) Predicate {
|
func (v Predicate) And(predicate Predicate) Predicate {
|
||||||
return All(this, predicate)
|
return All(v, predicate)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this Predicate) Or(predicate Predicate) Predicate {
|
func (v Predicate) Or(predicate Predicate) Predicate {
|
||||||
return Any(this, predicate)
|
return Any(v, predicate)
|
||||||
}
|
}
|
||||||
|
|
||||||
func All(predicates ...Predicate) Predicate {
|
func All(predicates ...Predicate) Predicate {
|
||||||
|
|
|
@ -19,16 +19,16 @@ const (
|
||||||
RequestOptionConnectionReuse = RequestOption(0x02)
|
RequestOptionConnectionReuse = RequestOption(0x02)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this RequestOption) Has(option RequestOption) bool {
|
func (v RequestOption) Has(option RequestOption) bool {
|
||||||
return (this & option) == option
|
return (v & option) == option
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RequestOption) Set(option RequestOption) {
|
func (v *RequestOption) Set(option RequestOption) {
|
||||||
*this = (*this | option)
|
*v = (*v | option)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RequestOption) Clear(option RequestOption) {
|
func (v *RequestOption) Clear(option RequestOption) {
|
||||||
*this = (*this & (^option))
|
*v = (*v & (^option))
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestHeader struct {
|
type RequestHeader struct {
|
||||||
|
@ -40,11 +40,11 @@ type RequestHeader struct {
|
||||||
Port v2net.Port
|
Port v2net.Port
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RequestHeader) Destination() v2net.Destination {
|
func (v *RequestHeader) Destination() v2net.Destination {
|
||||||
if this.Command == RequestCommandUDP {
|
if v.Command == RequestCommandUDP {
|
||||||
return v2net.UDPDestination(this.Address, this.Port)
|
return v2net.UDPDestination(v.Address, v.Port)
|
||||||
}
|
}
|
||||||
return v2net.TCPDestination(this.Address, this.Port)
|
return v2net.TCPDestination(v.Address, v.Port)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseOption byte
|
type ResponseOption byte
|
||||||
|
@ -53,16 +53,16 @@ const (
|
||||||
ResponseOptionConnectionReuse = ResponseOption(1)
|
ResponseOptionConnectionReuse = ResponseOption(1)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *ResponseOption) Set(option ResponseOption) {
|
func (v *ResponseOption) Set(option ResponseOption) {
|
||||||
*this = (*this | option)
|
*v = (*v | option)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this ResponseOption) Has(option ResponseOption) bool {
|
func (v ResponseOption) Has(option ResponseOption) bool {
|
||||||
return (this | option) == option
|
return (v | option) == option
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ResponseOption) Clear(option ResponseOption) {
|
func (v *ResponseOption) Clear(option ResponseOption) {
|
||||||
*this = (*this & (^option))
|
*v = (*v & (^option))
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseCommand interface{}
|
type ResponseCommand interface{}
|
||||||
|
|
|
@ -29,20 +29,20 @@ type ID struct {
|
||||||
cmdKey [IDBytesLen]byte
|
cmdKey [IDBytesLen]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ID) Equals(another *ID) bool {
|
func (v *ID) Equals(another *ID) bool {
|
||||||
return this.uuid.Equals(another.uuid)
|
return v.uuid.Equals(another.uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ID) Bytes() []byte {
|
func (v *ID) Bytes() []byte {
|
||||||
return this.uuid.Bytes()
|
return v.uuid.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ID) String() string {
|
func (v *ID) String() string {
|
||||||
return this.uuid.String()
|
return v.uuid.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ID) UUID() *uuid.UUID {
|
func (v *ID) UUID() *uuid.UUID {
|
||||||
return this.uuid
|
return v.uuid
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v ID) CmdKey() []byte {
|
func (v ID) CmdKey() []byte {
|
||||||
|
|
|
@ -13,32 +13,32 @@ func NewServerList() *ServerList {
|
||||||
return &ServerList{}
|
return &ServerList{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerList) AddServer(server *ServerSpec) {
|
func (v *ServerList) AddServer(server *ServerSpec) {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
this.servers = append(this.servers, server)
|
v.servers = append(v.servers, server)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerList) Size() uint32 {
|
func (v *ServerList) Size() uint32 {
|
||||||
this.RLock()
|
v.RLock()
|
||||||
defer this.RUnlock()
|
defer v.RUnlock()
|
||||||
|
|
||||||
return uint32(len(this.servers))
|
return uint32(len(v.servers))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerList) GetServer(idx uint32) *ServerSpec {
|
func (v *ServerList) GetServer(idx uint32) *ServerSpec {
|
||||||
this.RLock()
|
v.RLock()
|
||||||
defer this.RUnlock()
|
defer v.RUnlock()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if idx >= uint32(len(this.servers)) {
|
if idx >= uint32(len(v.servers)) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
server := this.servers[idx]
|
server := v.servers[idx]
|
||||||
if !server.IsValid() {
|
if !server.IsValid() {
|
||||||
this.RemoveServer(idx)
|
v.RemoveServer(idx)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,10 +47,10 @@ func (this *ServerList) GetServer(idx uint32) *ServerSpec {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private: Visible for testing.
|
// Private: Visible for testing.
|
||||||
func (this *ServerList) RemoveServer(idx uint32) {
|
func (v *ServerList) RemoveServer(idx uint32) {
|
||||||
n := len(this.servers)
|
n := len(v.servers)
|
||||||
this.servers[idx] = this.servers[n-1]
|
v.servers[idx] = v.servers[n-1]
|
||||||
this.servers = this.servers[:n-1]
|
v.servers = v.servers[:n-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerPicker interface {
|
type ServerPicker interface {
|
||||||
|
@ -70,21 +70,21 @@ func NewRoundRobinServerPicker(serverlist *ServerList) *RoundRobinServerPicker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RoundRobinServerPicker) PickServer() *ServerSpec {
|
func (v *RoundRobinServerPicker) PickServer() *ServerSpec {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
next := this.nextIndex
|
next := v.nextIndex
|
||||||
server := this.serverlist.GetServer(next)
|
server := v.serverlist.GetServer(next)
|
||||||
if server == nil {
|
if server == nil {
|
||||||
next = 0
|
next = 0
|
||||||
server = this.serverlist.GetServer(0)
|
server = v.serverlist.GetServer(0)
|
||||||
}
|
}
|
||||||
next++
|
next++
|
||||||
if next >= this.serverlist.Size() {
|
if next >= v.serverlist.Size() {
|
||||||
next = 0
|
next = 0
|
||||||
}
|
}
|
||||||
this.nextIndex = next
|
v.nextIndex = next
|
||||||
|
|
||||||
return server
|
return server
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,11 @@ func AlwaysValid() ValidationStrategy {
|
||||||
return AlwaysValidStrategy{}
|
return AlwaysValidStrategy{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this AlwaysValidStrategy) IsValid() bool {
|
func (v AlwaysValidStrategy) IsValid() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this AlwaysValidStrategy) Invalidate() {}
|
func (v AlwaysValidStrategy) Invalidate() {}
|
||||||
|
|
||||||
type TimeoutValidStrategy struct {
|
type TimeoutValidStrategy struct {
|
||||||
until time.Time
|
until time.Time
|
||||||
|
@ -35,12 +35,12 @@ func BeforeTime(t time.Time) ValidationStrategy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TimeoutValidStrategy) IsValid() bool {
|
func (v *TimeoutValidStrategy) IsValid() bool {
|
||||||
return this.until.After(time.Now())
|
return v.until.After(time.Now())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TimeoutValidStrategy) Invalidate() {
|
func (v *TimeoutValidStrategy) Invalidate() {
|
||||||
this.until = time.Time{}
|
v.until = time.Time{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerSpec struct {
|
type ServerSpec struct {
|
||||||
|
@ -63,19 +63,19 @@ func NewServerSpecFromPB(spec ServerEndpoint) *ServerSpec {
|
||||||
return NewServerSpec(dest, AlwaysValid(), spec.User...)
|
return NewServerSpec(dest, AlwaysValid(), spec.User...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerSpec) Destination() v2net.Destination {
|
func (v *ServerSpec) Destination() v2net.Destination {
|
||||||
return this.dest
|
return v.dest
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerSpec) HasUser(user *User) bool {
|
func (v *ServerSpec) HasUser(user *User) bool {
|
||||||
this.RLock()
|
v.RLock()
|
||||||
defer this.RUnlock()
|
defer v.RUnlock()
|
||||||
|
|
||||||
accountA, err := user.GetTypedAccount()
|
accountA, err := user.GetTypedAccount()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for _, u := range this.users {
|
for _, u := range v.users {
|
||||||
accountB, err := u.GetTypedAccount()
|
accountB, err := u.GetTypedAccount()
|
||||||
if err == nil && accountA.Equals(accountB) {
|
if err == nil && accountA.Equals(accountB) {
|
||||||
return true
|
return true
|
||||||
|
@ -84,26 +84,26 @@ func (this *ServerSpec) HasUser(user *User) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerSpec) AddUser(user *User) {
|
func (v *ServerSpec) AddUser(user *User) {
|
||||||
if this.HasUser(user) {
|
if v.HasUser(user) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
this.users = append(this.users, user)
|
v.users = append(v.users, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerSpec) PickUser() *User {
|
func (v *ServerSpec) PickUser() *User {
|
||||||
userCount := len(this.users)
|
userCount := len(v.users)
|
||||||
return this.users[dice.Roll(userCount)]
|
return v.users[dice.Roll(userCount)]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerSpec) IsValid() bool {
|
func (v *ServerSpec) IsValid() bool {
|
||||||
return this.valid.IsValid()
|
return v.valid.IsValid()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerSpec) Invalidate() {
|
func (v *ServerSpec) Invalidate() {
|
||||||
this.valid.Invalidate()
|
v.valid.Invalidate()
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
|
|
||||||
type Timestamp int64
|
type Timestamp int64
|
||||||
|
|
||||||
func (this Timestamp) Bytes(b []byte) []byte {
|
func (v Timestamp) Bytes(b []byte) []byte {
|
||||||
return serial.Int64ToBytes(int64(this), b)
|
return serial.Int64ToBytes(int64(v), b)
|
||||||
}
|
}
|
||||||
|
|
||||||
type TimestampGenerator func() Timestamp
|
type TimestampGenerator func() Timestamp
|
||||||
|
|
|
@ -11,12 +11,12 @@ var (
|
||||||
ErrUnknownAccountType = errors.New("Unknown account type.")
|
ErrUnknownAccountType = errors.New("Unknown account type.")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *User) GetTypedAccount() (Account, error) {
|
func (v *User) GetTypedAccount() (Account, error) {
|
||||||
if this.GetAccount() == nil {
|
if v.GetAccount() == nil {
|
||||||
return nil, ErrAccountMissing
|
return nil, ErrAccountMissing
|
||||||
}
|
}
|
||||||
|
|
||||||
rawAccount, err := this.Account.GetInstance()
|
rawAccount, err := v.Account.GetInstance()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -26,14 +26,14 @@ func (this *User) GetTypedAccount() (Account, error) {
|
||||||
if account, ok := rawAccount.(Account); ok {
|
if account, ok := rawAccount.(Account); ok {
|
||||||
return account, nil
|
return account, nil
|
||||||
}
|
}
|
||||||
return nil, errors.New("Unknown account type: " + this.Account.Type)
|
return nil, errors.New("Unknown account type: " + v.Account.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *User) GetSettings() UserSettings {
|
func (v *User) GetSettings() UserSettings {
|
||||||
settings := UserSettings{
|
settings := UserSettings{
|
||||||
PayloadReadTimeout: 120,
|
PayloadReadTimeout: 120,
|
||||||
}
|
}
|
||||||
if this.Level > 0 {
|
if v.Level > 0 {
|
||||||
settings.PayloadReadTimeout = 0
|
settings.PayloadReadTimeout = 0
|
||||||
}
|
}
|
||||||
return settings
|
return settings
|
||||||
|
|
|
@ -17,18 +17,18 @@ func NewCloseSignal() *CancelSignal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *CancelSignal) WaitThread() {
|
func (v *CancelSignal) WaitThread() {
|
||||||
this.done.Add(1)
|
v.done.Add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel signals the goroutine to stop.
|
// Cancel signals the goroutine to stop.
|
||||||
func (this *CancelSignal) Cancel() {
|
func (v *CancelSignal) Cancel() {
|
||||||
close(this.cancel)
|
close(v.cancel)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *CancelSignal) Cancelled() bool {
|
func (v *CancelSignal) Cancelled() bool {
|
||||||
select {
|
select {
|
||||||
case <-this.cancel:
|
case <-v.cancel:
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
|
@ -36,16 +36,16 @@ func (this *CancelSignal) Cancelled() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// WaitForCancel should be monitored by the goroutine for when to stop.
|
// WaitForCancel should be monitored by the goroutine for when to stop.
|
||||||
func (this *CancelSignal) WaitForCancel() <-chan struct{} {
|
func (v *CancelSignal) WaitForCancel() <-chan struct{} {
|
||||||
return this.cancel
|
return v.cancel
|
||||||
}
|
}
|
||||||
|
|
||||||
// FinishThread signals that current goroutine has finished.
|
// FinishThread signals that current goroutine has finished.
|
||||||
func (this *CancelSignal) FinishThread() {
|
func (v *CancelSignal) FinishThread() {
|
||||||
this.done.Done()
|
v.done.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
// WaitForDone is used by caller to wait for the goroutine finishes.
|
// WaitForDone is used by caller to wait for the goroutine finishes.
|
||||||
func (this *CancelSignal) WaitForDone() {
|
func (v *CancelSignal) WaitForDone() {
|
||||||
this.done.Wait()
|
v.done.Wait()
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,35 +17,35 @@ var (
|
||||||
type UUID [16]byte
|
type UUID [16]byte
|
||||||
|
|
||||||
// String returns the string representation of this UUID.
|
// String returns the string representation of this UUID.
|
||||||
func (this *UUID) String() string {
|
func (v *UUID) String() string {
|
||||||
return bytesToString(this.Bytes())
|
return bytesToString(v.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns the bytes representation of this UUID.
|
// Bytes returns the bytes representation of this UUID.
|
||||||
func (this *UUID) Bytes() []byte {
|
func (v *UUID) Bytes() []byte {
|
||||||
return this[:]
|
return v[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equals returns true if this UUID equals another UUID by value.
|
// Equals returns true if this UUID equals another UUID by value.
|
||||||
func (this *UUID) Equals(another *UUID) bool {
|
func (v *UUID) Equals(another *UUID) bool {
|
||||||
if this == nil && another == nil {
|
if v == nil && another == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if this == nil || another == nil {
|
if v == nil || another == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return bytes.Equal(this.Bytes(), another.Bytes())
|
return bytes.Equal(v.Bytes(), another.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next generates a deterministic random UUID based on this UUID.
|
// Next generates a deterministic random UUID based on this UUID.
|
||||||
func (this *UUID) Next() *UUID {
|
func (v *UUID) Next() *UUID {
|
||||||
md5hash := md5.New()
|
md5hash := md5.New()
|
||||||
md5hash.Write(this.Bytes())
|
md5hash.Write(v.Bytes())
|
||||||
md5hash.Write([]byte("16167dc8-16b6-4e6d-b8bb-65dd68113a81"))
|
md5hash.Write([]byte("16167dc8-16b6-4e6d-b8bb-65dd68113a81"))
|
||||||
newid := new(UUID)
|
newid := new(UUID)
|
||||||
for {
|
for {
|
||||||
md5hash.Sum(newid[:0])
|
md5hash.Sum(newid[:0])
|
||||||
if !newid.Equals(this) {
|
if !newid.Equals(v) {
|
||||||
return newid
|
return newid
|
||||||
}
|
}
|
||||||
md5hash.Write([]byte("533eff8a-4113-4b10-b5ce-0f5d76b98cd2"))
|
md5hash.Write([]byte("533eff8a-4113-4b10-b5ce-0f5d76b98cd2"))
|
||||||
|
|
42
config.go
42
config.go
|
@ -5,51 +5,51 @@ import (
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *AllocationStrategyConcurrency) GetValue() uint32 {
|
func (v *AllocationStrategyConcurrency) GetValue() uint32 {
|
||||||
if this == nil {
|
if v == nil {
|
||||||
return 3
|
return 3
|
||||||
}
|
}
|
||||||
return this.Value
|
return v.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AllocationStrategyRefresh) GetValue() uint32 {
|
func (v *AllocationStrategyRefresh) GetValue() uint32 {
|
||||||
if this == nil {
|
if v == nil {
|
||||||
return 5
|
return 5
|
||||||
}
|
}
|
||||||
return this.Value
|
return v.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundConnectionConfig) GetAllocationStrategyValue() *AllocationStrategy {
|
func (v *InboundConnectionConfig) GetAllocationStrategyValue() *AllocationStrategy {
|
||||||
if this.AllocationStrategy == nil {
|
if v.AllocationStrategy == nil {
|
||||||
return &AllocationStrategy{}
|
return &AllocationStrategy{}
|
||||||
}
|
}
|
||||||
return this.AllocationStrategy
|
return v.AllocationStrategy
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundConnectionConfig) GetListenOnValue() v2net.Address {
|
func (v *InboundConnectionConfig) GetListenOnValue() v2net.Address {
|
||||||
if this.GetListenOn() == nil {
|
if v.GetListenOn() == nil {
|
||||||
return v2net.AnyIP
|
return v2net.AnyIP
|
||||||
}
|
}
|
||||||
return this.ListenOn.AsAddress()
|
return v.ListenOn.AsAddress()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundConnectionConfig) GetTypedSettings() (interface{}, error) {
|
func (v *InboundConnectionConfig) GetTypedSettings() (interface{}, error) {
|
||||||
if this.GetSettings() == nil {
|
if v.GetSettings() == nil {
|
||||||
return nil, common.ErrBadConfiguration
|
return nil, common.ErrBadConfiguration
|
||||||
}
|
}
|
||||||
return this.GetSettings().GetInstance()
|
return v.GetSettings().GetInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *OutboundConnectionConfig) GetTypedSettings() (interface{}, error) {
|
func (v *OutboundConnectionConfig) GetTypedSettings() (interface{}, error) {
|
||||||
if this.GetSettings() == nil {
|
if v.GetSettings() == nil {
|
||||||
return nil, common.ErrBadConfiguration
|
return nil, common.ErrBadConfiguration
|
||||||
}
|
}
|
||||||
return this.GetSettings().GetInstance()
|
return v.GetSettings().GetInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *OutboundConnectionConfig) GetSendThroughValue() v2net.Address {
|
func (v *OutboundConnectionConfig) GetSendThroughValue() v2net.Address {
|
||||||
if this.GetSendThrough() == nil {
|
if v.GetSendThrough() == nil {
|
||||||
return v2net.AnyIP
|
return v2net.AnyIP
|
||||||
}
|
}
|
||||||
return this.SendThrough.AsAddress()
|
return v.SendThrough.AsAddress()
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,20 +44,20 @@ func NewInboundDetourHandlerAlways(space app.Space, config *InboundConnectionCon
|
||||||
return handler, nil
|
return handler, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundDetourHandlerAlways) GetConnectionHandler() (proxy.InboundHandler, int) {
|
func (v *InboundDetourHandlerAlways) GetConnectionHandler() (proxy.InboundHandler, int) {
|
||||||
ich := this.ich[dice.Roll(len(this.ich))]
|
ich := v.ich[dice.Roll(len(v.ich))]
|
||||||
return ich, int(this.config.GetAllocationStrategyValue().Refresh.GetValue())
|
return ich, int(v.config.GetAllocationStrategyValue().Refresh.GetValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundDetourHandlerAlways) Close() {
|
func (v *InboundDetourHandlerAlways) Close() {
|
||||||
for _, ich := range this.ich {
|
for _, ich := range v.ich {
|
||||||
ich.Close()
|
ich.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Starts the inbound connection handler.
|
// Starts the inbound connection handler.
|
||||||
func (this *InboundDetourHandlerAlways) Start() error {
|
func (v *InboundDetourHandlerAlways) Start() error {
|
||||||
for _, ich := range this.ich {
|
for _, ich := range v.ich {
|
||||||
err := retry.ExponentialBackoff(10 /* times */, 200 /* ms */).On(func() error {
|
err := retry.ExponentialBackoff(10 /* times */, 200 /* ms */).On(func() error {
|
||||||
err := ich.Start()
|
err := ich.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -52,74 +52,74 @@ func NewInboundDetourHandlerDynamic(space app.Space, config *InboundConnectionCo
|
||||||
return handler, nil
|
return handler, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundDetourHandlerDynamic) pickUnusedPort() v2net.Port {
|
func (v *InboundDetourHandlerDynamic) pickUnusedPort() v2net.Port {
|
||||||
delta := int(this.config.PortRange.To) - int(this.config.PortRange.From) + 1
|
delta := int(v.config.PortRange.To) - int(v.config.PortRange.From) + 1
|
||||||
for {
|
for {
|
||||||
r := dice.Roll(delta)
|
r := dice.Roll(delta)
|
||||||
port := this.config.PortRange.FromPort() + v2net.Port(r)
|
port := v.config.PortRange.FromPort() + v2net.Port(r)
|
||||||
_, used := this.portsInUse[port]
|
_, used := v.portsInUse[port]
|
||||||
if !used {
|
if !used {
|
||||||
return port
|
return port
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundDetourHandlerDynamic) GetConnectionHandler() (proxy.InboundHandler, int) {
|
func (v *InboundDetourHandlerDynamic) GetConnectionHandler() (proxy.InboundHandler, int) {
|
||||||
this.RLock()
|
v.RLock()
|
||||||
defer this.RUnlock()
|
defer v.RUnlock()
|
||||||
ich := this.ichs[dice.Roll(len(this.ichs))]
|
ich := v.ichs[dice.Roll(len(v.ichs))]
|
||||||
until := int(this.config.GetAllocationStrategyValue().Refresh.GetValue()) - int((time.Now().Unix()-this.lastRefresh.Unix())/60/1000)
|
until := int(v.config.GetAllocationStrategyValue().Refresh.GetValue()) - int((time.Now().Unix()-v.lastRefresh.Unix())/60/1000)
|
||||||
if until < 0 {
|
if until < 0 {
|
||||||
until = 0
|
until = 0
|
||||||
}
|
}
|
||||||
return ich, int(until)
|
return ich, int(until)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundDetourHandlerDynamic) Close() {
|
func (v *InboundDetourHandlerDynamic) Close() {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
for _, ich := range this.ichs {
|
for _, ich := range v.ichs {
|
||||||
ich.Close()
|
ich.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundDetourHandlerDynamic) RecyleHandles() {
|
func (v *InboundDetourHandlerDynamic) RecyleHandles() {
|
||||||
if this.ich2Recyle != nil {
|
if v.ich2Recyle != nil {
|
||||||
for _, ich := range this.ich2Recyle {
|
for _, ich := range v.ich2Recyle {
|
||||||
if ich == nil {
|
if ich == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
port := ich.Port()
|
port := ich.Port()
|
||||||
ich.Close()
|
ich.Close()
|
||||||
delete(this.portsInUse, port)
|
delete(v.portsInUse, port)
|
||||||
}
|
}
|
||||||
this.ich2Recyle = nil
|
v.ich2Recyle = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundDetourHandlerDynamic) refresh() error {
|
func (v *InboundDetourHandlerDynamic) refresh() error {
|
||||||
this.lastRefresh = time.Now()
|
v.lastRefresh = time.Now()
|
||||||
|
|
||||||
config := this.config
|
config := v.config
|
||||||
this.ich2Recyle = this.ichs
|
v.ich2Recyle = v.ichs
|
||||||
newIchs := make([]proxy.InboundHandler, config.GetAllocationStrategyValue().Concurrency.GetValue())
|
newIchs := make([]proxy.InboundHandler, config.GetAllocationStrategyValue().Concurrency.GetValue())
|
||||||
|
|
||||||
for idx := range newIchs {
|
for idx := range newIchs {
|
||||||
err := retry.Timed(5, 100).On(func() error {
|
err := retry.Timed(5, 100).On(func() error {
|
||||||
port := this.pickUnusedPort()
|
port := v.pickUnusedPort()
|
||||||
ichConfig, _ := config.GetTypedSettings()
|
ichConfig, _ := config.GetTypedSettings()
|
||||||
ich, err := proxyregistry.CreateInboundHandler(config.Settings.Type, this.space, ichConfig, &proxy.InboundHandlerMeta{
|
ich, err := proxyregistry.CreateInboundHandler(config.Settings.Type, v.space, ichConfig, &proxy.InboundHandlerMeta{
|
||||||
Address: config.GetListenOnValue(), Port: port, Tag: config.Tag, StreamSettings: config.StreamSettings})
|
Address: config.GetListenOnValue(), Port: port, Tag: config.Tag, StreamSettings: config.StreamSettings})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
delete(this.portsInUse, port)
|
delete(v.portsInUse, port)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = ich.Start()
|
err = ich.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
delete(this.portsInUse, port)
|
delete(v.portsInUse, port)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.portsInUse[port] = true
|
v.portsInUse[port] = true
|
||||||
newIchs[idx] = ich
|
newIchs[idx] = ich
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -129,15 +129,15 @@ func (this *InboundDetourHandlerDynamic) refresh() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Lock()
|
v.Lock()
|
||||||
this.ichs = newIchs
|
v.ichs = newIchs
|
||||||
this.Unlock()
|
v.Unlock()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundDetourHandlerDynamic) Start() error {
|
func (v *InboundDetourHandlerDynamic) Start() error {
|
||||||
err := this.refresh()
|
err := v.refresh()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Point: Failed to refresh dynamic allocations: ", err)
|
log.Error("Point: Failed to refresh dynamic allocations: ", err)
|
||||||
return err
|
return err
|
||||||
|
@ -145,9 +145,9 @@ func (this *InboundDetourHandlerDynamic) Start() error {
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
time.Sleep(time.Duration(this.config.GetAllocationStrategyValue().Refresh.GetValue())*time.Minute - 1)
|
time.Sleep(time.Duration(v.config.GetAllocationStrategyValue().Refresh.GetValue())*time.Minute - 1)
|
||||||
this.RecyleHandles()
|
v.RecyleHandles()
|
||||||
err := this.refresh()
|
err := v.refresh()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Point: Failed to refresh dynamic allocations: ", err)
|
log.Error("Point: Failed to refresh dynamic allocations: ", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,10 @@ func NewBlackHole(space app.Space, config *Config, meta *proxy.OutboundHandlerMe
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *BlackHole) Dispatch(destination v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
|
func (v *BlackHole) Dispatch(destination v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
|
||||||
payload.Release()
|
payload.Release()
|
||||||
|
|
||||||
this.response.WriteTo(ray.OutboundOutput())
|
v.response.WriteTo(ray.OutboundOutput())
|
||||||
ray.OutboundOutput().Close()
|
ray.OutboundOutput().Close()
|
||||||
|
|
||||||
ray.OutboundInput().Release()
|
ray.OutboundInput().Release()
|
||||||
|
@ -38,12 +38,12 @@ func (this *BlackHole) Dispatch(destination v2net.Destination, payload *alloc.Bu
|
||||||
|
|
||||||
type Factory struct{}
|
type Factory struct{}
|
||||||
|
|
||||||
func (this *Factory) StreamCapability() v2net.NetworkList {
|
func (v *Factory) StreamCapability() v2net.NetworkList {
|
||||||
return v2net.NetworkList{
|
return v2net.NetworkList{
|
||||||
Network: []v2net.Network{v2net.Network_RawTCP},
|
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Factory) Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
func (v *Factory) Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||||
return NewBlackHole(space, config.(*Config), meta)
|
return NewBlackHole(space, config.(*Config), meta)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,28 +23,28 @@ type ResponseConfig interface {
|
||||||
WriteTo(v2io.Writer)
|
WriteTo(v2io.Writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *NoneResponse) WriteTo(v2io.Writer) {}
|
func (v *NoneResponse) WriteTo(v2io.Writer) {}
|
||||||
|
|
||||||
func (this *NoneResponse) AsAny() *any.Any {
|
func (v *NoneResponse) AsAny() *any.Any {
|
||||||
r, _ := ptypes.MarshalAny(this)
|
r, _ := ptypes.MarshalAny(v)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *HTTPResponse) WriteTo(writer v2io.Writer) {
|
func (v *HTTPResponse) WriteTo(writer v2io.Writer) {
|
||||||
writer.Write(alloc.NewLocalBuffer(512).Clear().AppendString(http403response))
|
writer.Write(alloc.NewLocalBuffer(512).Clear().AppendString(http403response))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *HTTPResponse) AsAny() *any.Any {
|
func (v *HTTPResponse) AsAny() *any.Any {
|
||||||
r, _ := ptypes.MarshalAny(this)
|
r, _ := ptypes.MarshalAny(v)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Config) GetInternalResponse() (ResponseConfig, error) {
|
func (v *Config) GetInternalResponse() (ResponseConfig, error) {
|
||||||
if this.GetResponse() == nil {
|
if v.GetResponse() == nil {
|
||||||
return new(NoneResponse), nil
|
return new(NoneResponse), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
config, err := this.GetResponse().GetInstance()
|
config, err := v.GetResponse().GetInstance()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ import (
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Config) GetPredefinedAddress() v2net.Address {
|
func (v *Config) GetPredefinedAddress() v2net.Address {
|
||||||
addr := this.Address.AsAddress()
|
addr := v.Address.AsAddress()
|
||||||
if addr == nil {
|
if addr == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,40 +48,40 @@ func NewDokodemoDoor(config *Config, space app.Space, meta *proxy.InboundHandler
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DokodemoDoor) Port() v2net.Port {
|
func (v *DokodemoDoor) Port() v2net.Port {
|
||||||
return this.meta.Port
|
return v.meta.Port
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DokodemoDoor) Close() {
|
func (v *DokodemoDoor) Close() {
|
||||||
this.accepting = false
|
v.accepting = false
|
||||||
if this.tcpListener != nil {
|
if v.tcpListener != nil {
|
||||||
this.tcpMutex.Lock()
|
v.tcpMutex.Lock()
|
||||||
this.tcpListener.Close()
|
v.tcpListener.Close()
|
||||||
this.tcpListener = nil
|
v.tcpListener = nil
|
||||||
this.tcpMutex.Unlock()
|
v.tcpMutex.Unlock()
|
||||||
}
|
}
|
||||||
if this.udpHub != nil {
|
if v.udpHub != nil {
|
||||||
this.udpMutex.Lock()
|
v.udpMutex.Lock()
|
||||||
this.udpHub.Close()
|
v.udpHub.Close()
|
||||||
this.udpHub = nil
|
v.udpHub = nil
|
||||||
this.udpMutex.Unlock()
|
v.udpMutex.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DokodemoDoor) Start() error {
|
func (v *DokodemoDoor) Start() error {
|
||||||
if this.accepting {
|
if v.accepting {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
this.accepting = true
|
v.accepting = true
|
||||||
|
|
||||||
if this.config.NetworkList.HasNetwork(v2net.Network_TCP) {
|
if v.config.NetworkList.HasNetwork(v2net.Network_TCP) {
|
||||||
err := this.ListenTCP()
|
err := v.ListenTCP()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if this.config.NetworkList.HasNetwork(v2net.Network_UDP) {
|
if v.config.NetworkList.HasNetwork(v2net.Network_UDP) {
|
||||||
err := this.ListenUDP()
|
err := v.ListenUDP()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -89,71 +89,71 @@ func (this *DokodemoDoor) Start() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DokodemoDoor) ListenUDP() error {
|
func (v *DokodemoDoor) ListenUDP() error {
|
||||||
this.udpServer = udp.NewUDPServer(this.packetDispatcher)
|
v.udpServer = udp.NewUDPServer(v.packetDispatcher)
|
||||||
udpHub, err := udp.ListenUDP(
|
udpHub, err := udp.ListenUDP(
|
||||||
this.meta.Address, this.meta.Port, udp.ListenOption{
|
v.meta.Address, v.meta.Port, udp.ListenOption{
|
||||||
Callback: this.handleUDPPackets,
|
Callback: v.handleUDPPackets,
|
||||||
ReceiveOriginalDest: this.config.FollowRedirect,
|
ReceiveOriginalDest: v.config.FollowRedirect,
|
||||||
Concurrency: 2,
|
Concurrency: 2,
|
||||||
})
|
})
|
||||||
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 ", v.meta.Address, ":", v.meta.Port, ": ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.udpMutex.Lock()
|
v.udpMutex.Lock()
|
||||||
this.udpHub = udpHub
|
v.udpHub = udpHub
|
||||||
this.udpMutex.Unlock()
|
v.udpMutex.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, session *proxy.SessionInfo) {
|
func (v *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, session *proxy.SessionInfo) {
|
||||||
if session.Destination.Network == v2net.Network_Unknown && this.address != nil && this.port > 0 {
|
if session.Destination.Network == v2net.Network_Unknown && v.address != nil && v.port > 0 {
|
||||||
session.Destination = v2net.UDPDestination(this.address, this.port)
|
session.Destination = v2net.UDPDestination(v.address, v.port)
|
||||||
}
|
}
|
||||||
if session.Destination.Network == v2net.Network_Unknown {
|
if session.Destination.Network == v2net.Network_Unknown {
|
||||||
log.Info("Dokodemo: Unknown destination, stop forwarding...")
|
log.Info("Dokodemo: Unknown destination, stop forwarding...")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
session.Inbound = this.meta
|
session.Inbound = v.meta
|
||||||
this.udpServer.Dispatch(session, payload, this.handleUDPResponse)
|
v.udpServer.Dispatch(session, payload, v.handleUDPResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DokodemoDoor) handleUDPResponse(dest v2net.Destination, payload *alloc.Buffer) {
|
func (v *DokodemoDoor) handleUDPResponse(dest v2net.Destination, payload *alloc.Buffer) {
|
||||||
defer payload.Release()
|
defer payload.Release()
|
||||||
this.udpMutex.RLock()
|
v.udpMutex.RLock()
|
||||||
defer this.udpMutex.RUnlock()
|
defer v.udpMutex.RUnlock()
|
||||||
if !this.accepting {
|
if !v.accepting {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.udpHub.WriteTo(payload.Value, dest)
|
v.udpHub.WriteTo(payload.Value, dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DokodemoDoor) ListenTCP() error {
|
func (v *DokodemoDoor) ListenTCP() error {
|
||||||
tcpListener, err := internet.ListenTCP(this.meta.Address, this.meta.Port, this.HandleTCPConnection, this.meta.StreamSettings)
|
tcpListener, err := internet.ListenTCP(v.meta.Address, v.meta.Port, v.HandleTCPConnection, v.meta.StreamSettings)
|
||||||
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 ", v.meta.Address, ":", v.meta.Port, ": ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.tcpMutex.Lock()
|
v.tcpMutex.Lock()
|
||||||
this.tcpListener = tcpListener
|
v.tcpListener = tcpListener
|
||||||
this.tcpMutex.Unlock()
|
v.tcpMutex.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DokodemoDoor) HandleTCPConnection(conn internet.Connection) {
|
func (v *DokodemoDoor) HandleTCPConnection(conn internet.Connection) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
var dest v2net.Destination
|
var dest v2net.Destination
|
||||||
if this.config.FollowRedirect {
|
if v.config.FollowRedirect {
|
||||||
originalDest := GetOriginalDestination(conn)
|
originalDest := GetOriginalDestination(conn)
|
||||||
if originalDest.Network != v2net.Network_Unknown {
|
if originalDest.Network != v2net.Network_Unknown {
|
||||||
log.Info("Dokodemo: Following redirect to: ", originalDest)
|
log.Info("Dokodemo: Following redirect to: ", originalDest)
|
||||||
dest = originalDest
|
dest = originalDest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if dest.Network == v2net.Network_Unknown && this.address != nil && this.port > v2net.Port(0) {
|
if dest.Network == v2net.Network_Unknown && v.address != nil && v.port > v2net.Port(0) {
|
||||||
dest = v2net.TCPDestination(this.address, this.port)
|
dest = v2net.TCPDestination(v.address, v.port)
|
||||||
}
|
}
|
||||||
|
|
||||||
if dest.Network == v2net.Network_Unknown {
|
if dest.Network == v2net.Network_Unknown {
|
||||||
|
@ -162,16 +162,16 @@ 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(&proxy.SessionInfo{
|
ray := v.packetDispatcher.DispatchToOutbound(&proxy.SessionInfo{
|
||||||
Source: v2net.DestinationFromAddr(conn.RemoteAddr()),
|
Source: v2net.DestinationFromAddr(conn.RemoteAddr()),
|
||||||
Destination: dest,
|
Destination: dest,
|
||||||
Inbound: this.meta,
|
Inbound: v.meta,
|
||||||
})
|
})
|
||||||
defer ray.InboundOutput().Release()
|
defer ray.InboundOutput().Release()
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
reader := v2net.NewTimeOutReader(this.config.Timeout, conn)
|
reader := v2net.NewTimeOutReader(v.config.Timeout, conn)
|
||||||
defer reader.Release()
|
defer reader.Release()
|
||||||
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
@ -202,13 +202,13 @@ func (this *DokodemoDoor) HandleTCPConnection(conn internet.Connection) {
|
||||||
|
|
||||||
type Factory struct{}
|
type Factory struct{}
|
||||||
|
|
||||||
func (this *Factory) StreamCapability() v2net.NetworkList {
|
func (v *Factory) StreamCapability() v2net.NetworkList {
|
||||||
return v2net.NetworkList{
|
return v2net.NetworkList{
|
||||||
Network: []v2net.Network{v2net.Network_RawTCP},
|
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
func (v *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||||
return NewDokodemoDoor(rawConfig.(*Config), space, meta), nil
|
return NewDokodemoDoor(rawConfig.(*Config), space, meta), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,12 +45,12 @@ func NewFreedomConnection(config *Config, space app.Space, meta *proxy.OutboundH
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private: Visible for testing.
|
// Private: Visible for testing.
|
||||||
func (this *FreedomConnection) ResolveIP(destination v2net.Destination) v2net.Destination {
|
func (v *FreedomConnection) ResolveIP(destination v2net.Destination) v2net.Destination {
|
||||||
if !destination.Address.Family().IsDomain() {
|
if !destination.Address.Family().IsDomain() {
|
||||||
return destination
|
return destination
|
||||||
}
|
}
|
||||||
|
|
||||||
ips := this.dns.Get(destination.Address.Domain())
|
ips := v.dns.Get(destination.Address.Domain())
|
||||||
if len(ips) == 0 {
|
if len(ips) == 0 {
|
||||||
log.Info("Freedom: DNS returns nil answer. Keep domain as is.")
|
log.Info("Freedom: DNS returns nil answer. Keep domain as is.")
|
||||||
return destination
|
return destination
|
||||||
|
@ -67,7 +67,7 @@ func (this *FreedomConnection) ResolveIP(destination v2net.Destination) v2net.De
|
||||||
return newDest
|
return newDest
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *FreedomConnection) Dispatch(destination v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
|
func (v *FreedomConnection) Dispatch(destination v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
|
||||||
log.Info("Freedom: Opening connection to ", destination)
|
log.Info("Freedom: Opening connection to ", destination)
|
||||||
|
|
||||||
defer payload.Release()
|
defer payload.Release()
|
||||||
|
@ -75,11 +75,11 @@ 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 == Config_USE_IP && destination.Address.Family().IsDomain() {
|
if v.domainStrategy == Config_USE_IP && destination.Address.Family().IsDomain() {
|
||||||
destination = this.ResolveIP(destination)
|
destination = v.ResolveIP(destination)
|
||||||
}
|
}
|
||||||
err := retry.ExponentialBackoff(5, 100).On(func() error {
|
err := retry.ExponentialBackoff(5, 100).On(func() error {
|
||||||
rawConn, err := internet.Dial(this.meta.Address, destination, this.meta.GetDialerOptions())
|
rawConn, err := internet.Dial(v.meta.Address, destination, v.meta.GetDialerOptions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ func (this *FreedomConnection) Dispatch(destination v2net.Destination, payload *
|
||||||
|
|
||||||
var reader io.Reader = conn
|
var reader io.Reader = conn
|
||||||
|
|
||||||
timeout := this.timeout
|
timeout := v.timeout
|
||||||
if destination.Network == v2net.Network_UDP {
|
if destination.Network == v2net.Network_UDP {
|
||||||
timeout = 16
|
timeout = 16
|
||||||
}
|
}
|
||||||
|
@ -133,13 +133,13 @@ func (this *FreedomConnection) Dispatch(destination v2net.Destination, payload *
|
||||||
|
|
||||||
type FreedomFactory struct{}
|
type FreedomFactory struct{}
|
||||||
|
|
||||||
func (this *FreedomFactory) StreamCapability() v2net.NetworkList {
|
func (v *FreedomFactory) StreamCapability() v2net.NetworkList {
|
||||||
return v2net.NetworkList{
|
return v2net.NetworkList{
|
||||||
Network: []v2net.Network{v2net.Network_RawTCP},
|
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *FreedomFactory) Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
func (v *FreedomFactory) Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||||
return NewFreedomConnection(config.(*Config), space, meta), nil
|
return NewFreedomConnection(config.(*Config), space, meta), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,34 +40,34 @@ func NewServer(config *ServerConfig, packetDispatcher dispatcher.PacketDispatche
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) Port() v2net.Port {
|
func (v *Server) Port() v2net.Port {
|
||||||
return this.meta.Port
|
return v.meta.Port
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) Close() {
|
func (v *Server) Close() {
|
||||||
this.accepting = false
|
v.accepting = false
|
||||||
if this.tcpListener != nil {
|
if v.tcpListener != nil {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
this.tcpListener.Close()
|
v.tcpListener.Close()
|
||||||
this.tcpListener = nil
|
v.tcpListener = nil
|
||||||
this.Unlock()
|
v.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) Start() error {
|
func (v *Server) Start() error {
|
||||||
if this.accepting {
|
if v.accepting {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpListener, err := internet.ListenTCP(this.meta.Address, this.meta.Port, this.handleConnection, this.meta.StreamSettings)
|
tcpListener, err := internet.ListenTCP(v.meta.Address, v.meta.Port, v.handleConnection, v.meta.StreamSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("HTTP: Failed listen on ", this.meta.Address, ":", this.meta.Port, ": ", err)
|
log.Error("HTTP: Failed listen on ", v.meta.Address, ":", v.meta.Port, ": ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.Lock()
|
v.Lock()
|
||||||
this.tcpListener = tcpListener
|
v.tcpListener = tcpListener
|
||||||
this.Unlock()
|
v.Unlock()
|
||||||
this.accepting = true
|
v.accepting = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,9 +94,9 @@ func parseHost(rawHost string, defaultPort v2net.Port) (v2net.Destination, error
|
||||||
return v2net.TCPDestination(v2net.DomainAddress(host), port), nil
|
return v2net.TCPDestination(v2net.DomainAddress(host), port), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) handleConnection(conn internet.Connection) {
|
func (v *Server) handleConnection(conn internet.Connection) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
timedReader := v2net.NewTimeOutReader(this.config.Timeout, conn)
|
timedReader := v2net.NewTimeOutReader(v.config.Timeout, conn)
|
||||||
reader := bufio.NewReaderSize(timedReader, 2048)
|
reader := bufio.NewReaderSize(timedReader, 2048)
|
||||||
|
|
||||||
request, err := http.ReadRequest(reader)
|
request, err := http.ReadRequest(reader)
|
||||||
|
@ -124,16 +124,16 @@ func (this *Server) handleConnection(conn internet.Connection) {
|
||||||
session := &proxy.SessionInfo{
|
session := &proxy.SessionInfo{
|
||||||
Source: v2net.DestinationFromAddr(conn.RemoteAddr()),
|
Source: v2net.DestinationFromAddr(conn.RemoteAddr()),
|
||||||
Destination: dest,
|
Destination: dest,
|
||||||
Inbound: this.meta,
|
Inbound: v.meta,
|
||||||
}
|
}
|
||||||
if strings.ToUpper(request.Method) == "CONNECT" {
|
if strings.ToUpper(request.Method) == "CONNECT" {
|
||||||
this.handleConnect(request, session, reader, conn)
|
v.handleConnect(request, session, reader, conn)
|
||||||
} else {
|
} else {
|
||||||
this.handlePlainHTTP(request, session, reader, conn)
|
v.handlePlainHTTP(request, session, reader, conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) handleConnect(request *http.Request, session *proxy.SessionInfo, reader io.Reader, writer io.Writer) {
|
func (v *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,
|
||||||
|
@ -147,11 +147,11 @@ func (this *Server) handleConnect(request *http.Request, session *proxy.SessionI
|
||||||
}
|
}
|
||||||
response.Write(writer)
|
response.Write(writer)
|
||||||
|
|
||||||
ray := this.packetDispatcher.DispatchToOutbound(session)
|
ray := v.packetDispatcher.DispatchToOutbound(session)
|
||||||
this.transport(reader, writer, ray)
|
v.transport(reader, writer, ray)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) transport(input io.Reader, output io.Writer, ray ray.InboundRay) {
|
func (v *Server) transport(input io.Reader, output io.Writer, ray ray.InboundRay) {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(2)
|
wg.Add(2)
|
||||||
defer wg.Wait()
|
defer wg.Wait()
|
||||||
|
@ -204,7 +204,7 @@ func StripHopByHopHeaders(request *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) GenerateResponse(statusCode int, status string) *http.Response {
|
func (v *Server) GenerateResponse(statusCode int, status string) *http.Response {
|
||||||
hdr := http.Header(make(map[string][]string))
|
hdr := http.Header(make(map[string][]string))
|
||||||
hdr.Set("Connection", "close")
|
hdr.Set("Connection", "close")
|
||||||
return &http.Response{
|
return &http.Response{
|
||||||
|
@ -220,9 +220,9 @@ func (this *Server) GenerateResponse(statusCode int, status string) *http.Respon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) handlePlainHTTP(request *http.Request, session *proxy.SessionInfo, reader *bufio.Reader, writer io.Writer) {
|
func (v *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 := v.GenerateResponse(400, "Bad Request")
|
||||||
response.Write(writer)
|
response.Write(writer)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -231,7 +231,7 @@ func (this *Server) handlePlainHTTP(request *http.Request, session *proxy.Sessio
|
||||||
request.Host = request.URL.Host
|
request.Host = request.URL.Host
|
||||||
StripHopByHopHeaders(request)
|
StripHopByHopHeaders(request)
|
||||||
|
|
||||||
ray := this.packetDispatcher.DispatchToOutbound(session)
|
ray := v.packetDispatcher.DispatchToOutbound(session)
|
||||||
defer ray.InboundInput().Close()
|
defer ray.InboundInput().Close()
|
||||||
defer ray.InboundOutput().Release()
|
defer ray.InboundOutput().Release()
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ func (this *Server) handlePlainHTTP(request *http.Request, session *proxy.Sessio
|
||||||
response, err := http.ReadResponse(responseReader, request)
|
response, err := http.ReadResponse(responseReader, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warning("HTTP: Failed to read response: ", err)
|
log.Warning("HTTP: Failed to read response: ", err)
|
||||||
response = this.GenerateResponse(503, "Service Unavailable")
|
response = v.GenerateResponse(503, "Service Unavailable")
|
||||||
}
|
}
|
||||||
responseWriter := v2io.NewBufferedWriter(writer)
|
responseWriter := v2io.NewBufferedWriter(writer)
|
||||||
err = response.Write(responseWriter)
|
err = response.Write(responseWriter)
|
||||||
|
@ -270,13 +270,13 @@ func (this *Server) handlePlainHTTP(request *http.Request, session *proxy.Sessio
|
||||||
|
|
||||||
type ServerFactory struct{}
|
type ServerFactory struct{}
|
||||||
|
|
||||||
func (this *ServerFactory) StreamCapability() v2net.NetworkList {
|
func (v *ServerFactory) StreamCapability() v2net.NetworkList {
|
||||||
return v2net.NetworkList{
|
return v2net.NetworkList{
|
||||||
Network: []v2net.Network{v2net.Network_RawTCP},
|
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
func (v *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||||
if !space.HasApp(dispatcher.APP_ID) {
|
if !space.HasApp(dispatcher.APP_ID) {
|
||||||
return nil, common.ErrBadConfiguration
|
return nil, common.ErrBadConfiguration
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,10 +38,10 @@ type OutboundHandlerMeta struct {
|
||||||
ProxySettings *internet.ProxyConfig
|
ProxySettings *internet.ProxyConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *OutboundHandlerMeta) GetDialerOptions() internet.DialerOptions {
|
func (v *OutboundHandlerMeta) GetDialerOptions() internet.DialerOptions {
|
||||||
return internet.DialerOptions{
|
return internet.DialerOptions{
|
||||||
Stream: this.StreamSettings,
|
Stream: v.StreamSettings,
|
||||||
Proxy: this.ProxySettings,
|
Proxy: v.ProxySettings,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ func NewClient(config *ClientConfig, space app.Space, meta *proxy.OutboundHandle
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Client) Dispatch(destination v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
|
func (v *Client) Dispatch(destination v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
|
||||||
defer payload.Release()
|
defer payload.Release()
|
||||||
defer ray.OutboundInput().Release()
|
defer ray.OutboundInput().Release()
|
||||||
defer ray.OutboundOutput().Close()
|
defer ray.OutboundOutput().Close()
|
||||||
|
@ -44,10 +44,10 @@ func (this *Client) Dispatch(destination v2net.Destination, payload *alloc.Buffe
|
||||||
var conn internet.Connection
|
var conn internet.Connection
|
||||||
|
|
||||||
err := retry.ExponentialBackoff(5, 100).On(func() error {
|
err := retry.ExponentialBackoff(5, 100).On(func() error {
|
||||||
server = this.serverPicker.PickServer()
|
server = v.serverPicker.PickServer()
|
||||||
dest := server.Destination()
|
dest := server.Destination()
|
||||||
dest.Network = network
|
dest.Network = network
|
||||||
rawConn, err := internet.Dial(this.meta.Address, dest, this.meta.GetDialerOptions())
|
rawConn, err := internet.Dial(v.meta.Address, dest, v.meta.GetDialerOptions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -164,12 +164,12 @@ func (this *Client) Dispatch(destination v2net.Destination, payload *alloc.Buffe
|
||||||
|
|
||||||
type ClientFactory struct{}
|
type ClientFactory struct{}
|
||||||
|
|
||||||
func (this *ClientFactory) StreamCapability() v2net.NetworkList {
|
func (v *ClientFactory) StreamCapability() v2net.NetworkList {
|
||||||
return v2net.NetworkList{
|
return v2net.NetworkList{
|
||||||
Network: []v2net.Network{v2net.Network_TCP, v2net.Network_RawTCP},
|
Network: []v2net.Network{v2net.Network_TCP, v2net.Network_RawTCP},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ClientFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
func (v *ClientFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||||
return NewClient(rawConfig.(*ClientConfig), space, meta)
|
return NewClient(rawConfig.(*ClientConfig), space, meta)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,15 +16,15 @@ type ShadowsocksAccount struct {
|
||||||
OneTimeAuth Account_OneTimeAuth
|
OneTimeAuth Account_OneTimeAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ShadowsocksAccount) Equals(another protocol.Account) bool {
|
func (v *ShadowsocksAccount) Equals(another protocol.Account) bool {
|
||||||
if account, ok := another.(*ShadowsocksAccount); ok {
|
if account, ok := another.(*ShadowsocksAccount); ok {
|
||||||
return bytes.Equal(this.Key, account.Key)
|
return bytes.Equal(v.Key, account.Key)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Account) GetCipher() (Cipher, error) {
|
func (v *Account) GetCipher() (Cipher, error) {
|
||||||
switch this.CipherType {
|
switch v.CipherType {
|
||||||
case CipherType_AES_128_CFB:
|
case CipherType_AES_128_CFB:
|
||||||
return &AesCfb{KeyBytes: 16}, nil
|
return &AesCfb{KeyBytes: 16}, nil
|
||||||
case CipherType_AES_256_CFB:
|
case CipherType_AES_256_CFB:
|
||||||
|
@ -38,24 +38,24 @@ func (this *Account) GetCipher() (Cipher, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Account) AsAccount() (protocol.Account, error) {
|
func (v *Account) AsAccount() (protocol.Account, error) {
|
||||||
cipher, err := this.GetCipher()
|
cipher, err := v.GetCipher()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &ShadowsocksAccount{
|
return &ShadowsocksAccount{
|
||||||
Cipher: cipher,
|
Cipher: cipher,
|
||||||
Key: this.GetCipherKey(),
|
Key: v.GetCipherKey(),
|
||||||
OneTimeAuth: this.Ota,
|
OneTimeAuth: v.Ota,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Account) GetCipherKey() []byte {
|
func (v *Account) GetCipherKey() []byte {
|
||||||
ct, err := this.GetCipher()
|
ct, err := v.GetCipher()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return PasswordToCipherKey(this.Password, ct.KeySize())
|
return PasswordToCipherKey(v.Password, ct.KeySize())
|
||||||
}
|
}
|
||||||
|
|
||||||
type Cipher interface {
|
type Cipher interface {
|
||||||
|
@ -69,20 +69,20 @@ type AesCfb struct {
|
||||||
KeyBytes int
|
KeyBytes int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AesCfb) KeySize() int {
|
func (v *AesCfb) KeySize() int {
|
||||||
return this.KeyBytes
|
return v.KeyBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AesCfb) IVSize() int {
|
func (v *AesCfb) IVSize() int {
|
||||||
return 16
|
return 16
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AesCfb) NewEncodingStream(key []byte, iv []byte) (cipher.Stream, error) {
|
func (v *AesCfb) NewEncodingStream(key []byte, iv []byte) (cipher.Stream, error) {
|
||||||
stream := crypto.NewAesEncryptionStream(key, iv)
|
stream := crypto.NewAesEncryptionStream(key, iv)
|
||||||
return stream, nil
|
return stream, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AesCfb) NewDecodingStream(key []byte, iv []byte) (cipher.Stream, error) {
|
func (v *AesCfb) NewDecodingStream(key []byte, iv []byte) (cipher.Stream, error) {
|
||||||
stream := crypto.NewAesDecryptionStream(key, iv)
|
stream := crypto.NewAesDecryptionStream(key, iv)
|
||||||
return stream, nil
|
return stream, nil
|
||||||
}
|
}
|
||||||
|
@ -91,19 +91,19 @@ type ChaCha20 struct {
|
||||||
IVBytes int
|
IVBytes int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ChaCha20) KeySize() int {
|
func (v *ChaCha20) KeySize() int {
|
||||||
return 32
|
return 32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ChaCha20) IVSize() int {
|
func (v *ChaCha20) IVSize() int {
|
||||||
return this.IVBytes
|
return v.IVBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ChaCha20) NewEncodingStream(key []byte, iv []byte) (cipher.Stream, error) {
|
func (v *ChaCha20) NewEncodingStream(key []byte, iv []byte) (cipher.Stream, error) {
|
||||||
return crypto.NewChaCha20Stream(key, iv), nil
|
return crypto.NewChaCha20Stream(key, iv), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ChaCha20) NewDecodingStream(key []byte, iv []byte) (cipher.Stream, error) {
|
func (v *ChaCha20) NewDecodingStream(key []byte, iv []byte) (cipher.Stream, error) {
|
||||||
return crypto.NewChaCha20Stream(key, iv), nil
|
return crypto.NewChaCha20Stream(key, iv), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@ func NewAuthenticator(keygen KeyGenerator) *Authenticator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Authenticator) Authenticate(auth []byte, data []byte) []byte {
|
func (v *Authenticator) Authenticate(auth []byte, data []byte) []byte {
|
||||||
hasher := hmac.New(sha1.New, this.key())
|
hasher := hmac.New(sha1.New, v.key())
|
||||||
hasher.Write(data)
|
hasher.Write(data)
|
||||||
res := hasher.Sum(nil)
|
res := hasher.Sum(nil)
|
||||||
return append(auth, res[:AuthSize]...)
|
return append(auth, res[:AuthSize]...)
|
||||||
|
@ -65,14 +65,14 @@ func NewChunkReader(reader io.Reader, auth *Authenticator) *ChunkReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ChunkReader) Release() {
|
func (v *ChunkReader) Release() {
|
||||||
this.reader = nil
|
v.reader = nil
|
||||||
this.auth = nil
|
v.auth = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ChunkReader) Read() (*alloc.Buffer, error) {
|
func (v *ChunkReader) Read() (*alloc.Buffer, error) {
|
||||||
buffer := alloc.NewBuffer()
|
buffer := alloc.NewBuffer()
|
||||||
if _, err := io.ReadFull(this.reader, buffer.Value[:2]); err != nil {
|
if _, err := io.ReadFull(v.reader, buffer.Value[:2]); err != nil {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ func (this *ChunkReader) Read() (*alloc.Buffer, error) {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
buffer = alloc.NewLocalBuffer(int(length) + 128)
|
buffer = alloc.NewLocalBuffer(int(length) + 128)
|
||||||
}
|
}
|
||||||
if _, err := io.ReadFull(this.reader, buffer.Value[:length]); err != nil {
|
if _, err := io.ReadFull(v.reader, buffer.Value[:length]); err != nil {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ func (this *ChunkReader) Read() (*alloc.Buffer, error) {
|
||||||
authBytes := buffer.Value[:AuthSize]
|
authBytes := buffer.Value[:AuthSize]
|
||||||
payload := buffer.Value[AuthSize:]
|
payload := buffer.Value[AuthSize:]
|
||||||
|
|
||||||
actualAuthBytes := this.auth.Authenticate(nil, payload)
|
actualAuthBytes := v.auth.Authenticate(nil, payload)
|
||||||
if !bytes.Equal(authBytes, actualAuthBytes) {
|
if !bytes.Equal(authBytes, actualAuthBytes) {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, errors.New("Shadowsocks|AuthenticationReader: Invalid auth.")
|
return nil, errors.New("Shadowsocks|AuthenticationReader: Invalid auth.")
|
||||||
|
@ -115,16 +115,16 @@ func NewChunkWriter(writer io.Writer, auth *Authenticator) *ChunkWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ChunkWriter) Release() {
|
func (v *ChunkWriter) Release() {
|
||||||
this.writer = nil
|
v.writer = nil
|
||||||
this.auth = nil
|
v.auth = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ChunkWriter) Write(payload *alloc.Buffer) error {
|
func (v *ChunkWriter) Write(payload *alloc.Buffer) error {
|
||||||
totalLength := payload.Len()
|
totalLength := payload.Len()
|
||||||
payload.SliceBack(AuthSize)
|
payload.SliceBack(AuthSize)
|
||||||
this.auth.Authenticate(payload.Value[:0], payload.Value[AuthSize:])
|
v.auth.Authenticate(payload.Value[:0], payload.Value[AuthSize:])
|
||||||
payload.PrependUint16(uint16(totalLength))
|
payload.PrependUint16(uint16(totalLength))
|
||||||
_, err := this.writer.Write(payload.Bytes())
|
_, err := v.writer.Write(payload.Bytes())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -364,15 +364,15 @@ type UDPReader struct {
|
||||||
User *protocol.User
|
User *protocol.User
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *UDPReader) Read() (*alloc.Buffer, error) {
|
func (v *UDPReader) Read() (*alloc.Buffer, error) {
|
||||||
buffer := alloc.NewSmallBuffer()
|
buffer := alloc.NewSmallBuffer()
|
||||||
nBytes, err := this.Reader.Read(buffer.Value)
|
nBytes, err := v.Reader.Read(buffer.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
buffer.Slice(0, nBytes)
|
buffer.Slice(0, nBytes)
|
||||||
_, payload, err := DecodeUDPPacket(this.User, buffer)
|
_, payload, err := DecodeUDPPacket(v.User, buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -380,7 +380,7 @@ func (this *UDPReader) Read() (*alloc.Buffer, error) {
|
||||||
return payload, nil
|
return payload, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *UDPReader) Release() {
|
func (v *UDPReader) Release() {
|
||||||
}
|
}
|
||||||
|
|
||||||
type UDPWriter struct {
|
type UDPWriter struct {
|
||||||
|
@ -388,16 +388,16 @@ type UDPWriter struct {
|
||||||
Request *protocol.RequestHeader
|
Request *protocol.RequestHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *UDPWriter) Write(buffer *alloc.Buffer) error {
|
func (v *UDPWriter) Write(buffer *alloc.Buffer) error {
|
||||||
payload, err := EncodeUDPPacket(this.Request, buffer)
|
payload, err := EncodeUDPPacket(v.Request, buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = this.Writer.Write(payload.Value)
|
_, err = v.Writer.Write(payload.Value)
|
||||||
payload.Release()
|
payload.Release()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *UDPWriter) Release() {
|
func (v *UDPWriter) Release() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,54 +59,54 @@ func NewServer(config *ServerConfig, space app.Space, meta *proxy.InboundHandler
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) Port() v2net.Port {
|
func (v *Server) Port() v2net.Port {
|
||||||
return this.meta.Port
|
return v.meta.Port
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) Close() {
|
func (v *Server) Close() {
|
||||||
this.accepting = false
|
v.accepting = false
|
||||||
// TODO: synchronization
|
// TODO: synchronization
|
||||||
if this.tcpHub != nil {
|
if v.tcpHub != nil {
|
||||||
this.tcpHub.Close()
|
v.tcpHub.Close()
|
||||||
this.tcpHub = nil
|
v.tcpHub = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.udpHub != nil {
|
if v.udpHub != nil {
|
||||||
this.udpHub.Close()
|
v.udpHub.Close()
|
||||||
this.udpHub = nil
|
v.udpHub = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) Start() error {
|
func (v *Server) Start() error {
|
||||||
if this.accepting {
|
if v.accepting {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpHub, err := internet.ListenTCP(this.meta.Address, this.meta.Port, this.handleConnection, this.meta.StreamSettings)
|
tcpHub, err := internet.ListenTCP(v.meta.Address, v.meta.Port, v.handleConnection, v.meta.StreamSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Shadowsocks: Failed to listen TCP on ", this.meta.Address, ":", this.meta.Port, ": ", err)
|
log.Error("Shadowsocks: Failed to listen TCP on ", v.meta.Address, ":", v.meta.Port, ": ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.tcpHub = tcpHub
|
v.tcpHub = tcpHub
|
||||||
|
|
||||||
if this.config.UdpEnabled {
|
if v.config.UdpEnabled {
|
||||||
this.udpServer = udp.NewUDPServer(this.packetDispatcher)
|
v.udpServer = udp.NewUDPServer(v.packetDispatcher)
|
||||||
udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, udp.ListenOption{Callback: this.handlerUDPPayload})
|
udpHub, err := udp.ListenUDP(v.meta.Address, v.meta.Port, udp.ListenOption{Callback: v.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 ", v.meta.Address, ":", v.meta.Port, ": ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.udpHub = udpHub
|
v.udpHub = udpHub
|
||||||
}
|
}
|
||||||
|
|
||||||
this.accepting = true
|
v.accepting = true
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) handlerUDPPayload(payload *alloc.Buffer, session *proxy.SessionInfo) {
|
func (v *Server) handlerUDPPayload(payload *alloc.Buffer, session *proxy.SessionInfo) {
|
||||||
source := session.Source
|
source := session.Source
|
||||||
request, data, err := DecodeUDPPacket(this.user, payload)
|
request, data, err := DecodeUDPPacket(v.user, payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Shadowsocks|Server: Skipping invalid UDP packet from: ", source, ": ", err)
|
log.Info("Shadowsocks|Server: Skipping invalid UDP packet from: ", source, ": ", err)
|
||||||
log.Access(source, "", log.AccessRejected, err)
|
log.Access(source, "", log.AccessRejected, err)
|
||||||
|
@ -114,13 +114,13 @@ func (this *Server) handlerUDPPayload(payload *alloc.Buffer, session *proxy.Sess
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if request.Option.Has(RequestOptionOneTimeAuth) && this.account.OneTimeAuth == Account_Disabled {
|
if request.Option.Has(RequestOptionOneTimeAuth) && v.account.OneTimeAuth == Account_Disabled {
|
||||||
log.Info("Shadowsocks|Server: Client payload enables OTA but server doesn't allow it.")
|
log.Info("Shadowsocks|Server: Client payload enables OTA but server doesn't allow it.")
|
||||||
payload.Release()
|
payload.Release()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !request.Option.Has(RequestOptionOneTimeAuth) && this.account.OneTimeAuth == Account_Enabled {
|
if !request.Option.Has(RequestOptionOneTimeAuth) && v.account.OneTimeAuth == Account_Enabled {
|
||||||
log.Info("Shadowsocks|Server: Client payload disables OTA but server forces it.")
|
log.Info("Shadowsocks|Server: Client payload disables OTA but server forces it.")
|
||||||
payload.Release()
|
payload.Release()
|
||||||
return
|
return
|
||||||
|
@ -130,7 +130,7 @@ func (this *Server) handlerUDPPayload(payload *alloc.Buffer, session *proxy.Sess
|
||||||
log.Access(source, dest, log.AccessAccepted, "")
|
log.Access(source, dest, log.AccessAccepted, "")
|
||||||
log.Info("Shadowsocks|Server: Tunnelling request to ", dest)
|
log.Info("Shadowsocks|Server: Tunnelling request to ", dest)
|
||||||
|
|
||||||
this.udpServer.Dispatch(&proxy.SessionInfo{Source: source, Destination: dest, User: request.User, Inbound: this.meta}, data, func(destination v2net.Destination, payload *alloc.Buffer) {
|
v.udpServer.Dispatch(&proxy.SessionInfo{Source: source, Destination: dest, User: request.User, Inbound: v.meta}, data, func(destination v2net.Destination, payload *alloc.Buffer) {
|
||||||
defer payload.Release()
|
defer payload.Release()
|
||||||
|
|
||||||
data, err := EncodeUDPPacket(request, payload)
|
data, err := EncodeUDPPacket(request, payload)
|
||||||
|
@ -140,11 +140,11 @@ func (this *Server) handlerUDPPayload(payload *alloc.Buffer, session *proxy.Sess
|
||||||
}
|
}
|
||||||
defer data.Release()
|
defer data.Release()
|
||||||
|
|
||||||
this.udpHub.WriteTo(data.Value, source)
|
v.udpHub.WriteTo(data.Value, source)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) handleConnection(conn internet.Connection) {
|
func (v *Server) handleConnection(conn internet.Connection) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
conn.SetReusable(false)
|
conn.SetReusable(false)
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ func (this *Server) handleConnection(conn internet.Connection) {
|
||||||
bufferedReader := v2io.NewBufferedReader(timedReader)
|
bufferedReader := v2io.NewBufferedReader(timedReader)
|
||||||
defer bufferedReader.Release()
|
defer bufferedReader.Release()
|
||||||
|
|
||||||
request, bodyReader, err := ReadTCPSession(this.user, bufferedReader)
|
request, bodyReader, err := ReadTCPSession(v.user, bufferedReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Access(conn.RemoteAddr(), "", log.AccessRejected, err)
|
log.Access(conn.RemoteAddr(), "", log.AccessRejected, err)
|
||||||
log.Info("Shadowsocks|Server: Failed to create request from: ", conn.RemoteAddr(), ": ", err)
|
log.Info("Shadowsocks|Server: Failed to create request from: ", conn.RemoteAddr(), ": ", err)
|
||||||
|
@ -164,18 +164,18 @@ func (this *Server) handleConnection(conn internet.Connection) {
|
||||||
|
|
||||||
bufferedReader.SetCached(false)
|
bufferedReader.SetCached(false)
|
||||||
|
|
||||||
userSettings := this.user.GetSettings()
|
userSettings := v.user.GetSettings()
|
||||||
timedReader.SetTimeOut(userSettings.PayloadReadTimeout)
|
timedReader.SetTimeOut(userSettings.PayloadReadTimeout)
|
||||||
|
|
||||||
dest := request.Destination()
|
dest := request.Destination()
|
||||||
log.Access(conn.RemoteAddr(), dest, log.AccessAccepted, "")
|
log.Access(conn.RemoteAddr(), dest, log.AccessAccepted, "")
|
||||||
log.Info("Shadowsocks|Server: Tunnelling request to ", dest)
|
log.Info("Shadowsocks|Server: Tunnelling request to ", dest)
|
||||||
|
|
||||||
ray := this.packetDispatcher.DispatchToOutbound(&proxy.SessionInfo{
|
ray := v.packetDispatcher.DispatchToOutbound(&proxy.SessionInfo{
|
||||||
Source: v2net.DestinationFromAddr(conn.RemoteAddr()),
|
Source: v2net.DestinationFromAddr(conn.RemoteAddr()),
|
||||||
Destination: dest,
|
Destination: dest,
|
||||||
User: request.User,
|
User: request.User,
|
||||||
Inbound: this.meta,
|
Inbound: v.meta,
|
||||||
})
|
})
|
||||||
defer ray.InboundOutput().Release()
|
defer ray.InboundOutput().Release()
|
||||||
|
|
||||||
|
@ -214,13 +214,13 @@ func (this *Server) handleConnection(conn internet.Connection) {
|
||||||
|
|
||||||
type ServerFactory struct{}
|
type ServerFactory struct{}
|
||||||
|
|
||||||
func (this *ServerFactory) StreamCapability() v2net.NetworkList {
|
func (v *ServerFactory) StreamCapability() v2net.NetworkList {
|
||||||
return v2net.NetworkList{
|
return v2net.NetworkList{
|
||||||
Network: []v2net.Network{v2net.Network_TCP, v2net.Network_RawTCP},
|
Network: []v2net.Network{v2net.Network_TCP, v2net.Network_RawTCP},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
func (v *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||||
if !space.HasApp(dispatcher.APP_ID) {
|
if !space.HasApp(dispatcher.APP_ID) {
|
||||||
return nil, common.ErrBadConfiguration
|
return nil, common.ErrBadConfiguration
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,39 +8,39 @@ import (
|
||||||
google_protobuf "github.com/golang/protobuf/ptypes/any"
|
google_protobuf "github.com/golang/protobuf/ptypes/any"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Account) Equals(another protocol.Account) bool {
|
func (v *Account) Equals(another protocol.Account) bool {
|
||||||
if account, ok := another.(*Account); ok {
|
if account, ok := another.(*Account); ok {
|
||||||
return this.Username == account.Username
|
return v.Username == account.Username
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Account) AsAccount() (protocol.Account, error) {
|
func (v *Account) AsAccount() (protocol.Account, error) {
|
||||||
return this, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAccount() protocol.AsAccount {
|
func NewAccount() protocol.AsAccount {
|
||||||
return &Account{}
|
return &Account{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Account) AsAny() (*google_protobuf.Any, error) {
|
func (v *Account) AsAny() (*google_protobuf.Any, error) {
|
||||||
return ptypes.MarshalAny(this)
|
return ptypes.MarshalAny(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerConfig) HasAccount(username, password string) bool {
|
func (v *ServerConfig) HasAccount(username, password string) bool {
|
||||||
if this.Accounts == nil {
|
if v.Accounts == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
storedPassed, found := this.Accounts[username]
|
storedPassed, found := v.Accounts[username]
|
||||||
if !found {
|
if !found {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return storedPassed == password
|
return storedPassed == password
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerConfig) GetNetAddress() v2net.Address {
|
func (v *ServerConfig) GetNetAddress() v2net.Address {
|
||||||
if this.Address == nil {
|
if v.Address == nil {
|
||||||
return v2net.LocalHostIP
|
return v2net.LocalHostIP
|
||||||
}
|
}
|
||||||
return this.Address.AsAddress()
|
return v.Address.AsAddress()
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,56 +55,56 @@ func NewServer(config *ServerConfig, space app.Space, meta *proxy.InboundHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
// Port implements InboundHandler.Port().
|
// Port implements InboundHandler.Port().
|
||||||
func (this *Server) Port() v2net.Port {
|
func (v *Server) Port() v2net.Port {
|
||||||
return this.meta.Port
|
return v.meta.Port
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close implements InboundHandler.Close().
|
// Close implements InboundHandler.Close().
|
||||||
func (this *Server) Close() {
|
func (v *Server) Close() {
|
||||||
this.accepting = false
|
v.accepting = false
|
||||||
if this.tcpListener != nil {
|
if v.tcpListener != nil {
|
||||||
this.tcpMutex.Lock()
|
v.tcpMutex.Lock()
|
||||||
this.tcpListener.Close()
|
v.tcpListener.Close()
|
||||||
this.tcpListener = nil
|
v.tcpListener = nil
|
||||||
this.tcpMutex.Unlock()
|
v.tcpMutex.Unlock()
|
||||||
}
|
}
|
||||||
if this.udpHub != nil {
|
if v.udpHub != nil {
|
||||||
this.udpMutex.Lock()
|
v.udpMutex.Lock()
|
||||||
this.udpHub.Close()
|
v.udpHub.Close()
|
||||||
this.udpHub = nil
|
v.udpHub = nil
|
||||||
this.udpMutex.Unlock()
|
v.udpMutex.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen implements InboundHandler.Listen().
|
// Listen implements InboundHandler.Listen().
|
||||||
func (this *Server) Start() error {
|
func (v *Server) Start() error {
|
||||||
if this.accepting {
|
if v.accepting {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
listener, err := internet.ListenTCP(
|
listener, err := internet.ListenTCP(
|
||||||
this.meta.Address,
|
v.meta.Address,
|
||||||
this.meta.Port,
|
v.meta.Port,
|
||||||
this.handleConnection,
|
v.handleConnection,
|
||||||
this.meta.StreamSettings)
|
v.meta.StreamSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Socks: failed to listen on ", this.meta.Address, ":", this.meta.Port, ": ", err)
|
log.Error("Socks: failed to listen on ", v.meta.Address, ":", v.meta.Port, ": ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.accepting = true
|
v.accepting = true
|
||||||
this.tcpMutex.Lock()
|
v.tcpMutex.Lock()
|
||||||
this.tcpListener = listener
|
v.tcpListener = listener
|
||||||
this.tcpMutex.Unlock()
|
v.tcpMutex.Unlock()
|
||||||
if this.config.UdpEnabled {
|
if v.config.UdpEnabled {
|
||||||
this.listenUDP()
|
v.listenUDP()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) handleConnection(connection internet.Connection) {
|
func (v *Server) handleConnection(connection internet.Connection) {
|
||||||
defer connection.Close()
|
defer connection.Close()
|
||||||
|
|
||||||
timedReader := v2net.NewTimeOutReader(this.config.Timeout, connection)
|
timedReader := v2net.NewTimeOutReader(v.config.Timeout, connection)
|
||||||
reader := v2io.NewBufferedReader(timedReader)
|
reader := v2io.NewBufferedReader(timedReader)
|
||||||
defer reader.Release()
|
defer reader.Release()
|
||||||
|
|
||||||
|
@ -121,15 +121,15 @@ func (this *Server) handleConnection(connection internet.Connection) {
|
||||||
|
|
||||||
clientAddr := v2net.DestinationFromAddr(connection.RemoteAddr())
|
clientAddr := v2net.DestinationFromAddr(connection.RemoteAddr())
|
||||||
if err != nil && err == protocol.Socks4Downgrade {
|
if err != nil && err == protocol.Socks4Downgrade {
|
||||||
this.handleSocks4(clientAddr, reader, writer, auth4)
|
v.handleSocks4(clientAddr, reader, writer, auth4)
|
||||||
} else {
|
} else {
|
||||||
this.handleSocks5(clientAddr, reader, writer, auth)
|
v.handleSocks5(clientAddr, reader, writer, auth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) handleSocks5(clientAddr v2net.Destination, reader *v2io.BufferedReader, writer *v2io.BufferedWriter, auth protocol.Socks5AuthenticationRequest) error {
|
func (v *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 == AuthType_PASSWORD {
|
if v.config.AuthType == AuthType_PASSWORD {
|
||||||
expectedAuthMethod = protocol.AuthUserPass
|
expectedAuthMethod = protocol.AuthUserPass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,14 +152,14 @@ func (this *Server) handleSocks5(clientAddr v2net.Destination, reader *v2io.Buff
|
||||||
log.Error("Socks: failed to write authentication: ", err)
|
log.Error("Socks: failed to write authentication: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if this.config.AuthType == AuthType_PASSWORD {
|
if v.config.AuthType == AuthType_PASSWORD {
|
||||||
upRequest, err := protocol.ReadUserPassRequest(reader)
|
upRequest, err := protocol.ReadUserPassRequest(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warning("Socks: failed to read username and password: ", err)
|
log.Warning("Socks: failed to read username and password: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
status := byte(0)
|
status := byte(0)
|
||||||
if !this.config.HasAccount(upRequest.Username(), upRequest.Password()) {
|
if !v.config.HasAccount(upRequest.Username(), upRequest.Password()) {
|
||||||
status = byte(0xFF)
|
status = byte(0xFF)
|
||||||
}
|
}
|
||||||
upResponse := protocol.NewSocks5UserPassResponse(status)
|
upResponse := protocol.NewSocks5UserPassResponse(status)
|
||||||
|
@ -182,8 +182,8 @@ func (this *Server) handleSocks5(clientAddr v2net.Destination, reader *v2io.Buff
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if request.Command == protocol.CmdUdpAssociate && this.config.UdpEnabled {
|
if request.Command == protocol.CmdUdpAssociate && v.config.UdpEnabled {
|
||||||
return this.handleUDP(reader, writer)
|
return v.handleUDP(reader, writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if request.Command == protocol.CmdBind || request.Command == protocol.CmdUdpAssociate {
|
if request.Command == protocol.CmdBind || request.Command == protocol.CmdUdpAssociate {
|
||||||
|
@ -222,20 +222,20 @@ func (this *Server) handleSocks5(clientAddr v2net.Destination, reader *v2io.Buff
|
||||||
session := &proxy.SessionInfo{
|
session := &proxy.SessionInfo{
|
||||||
Source: clientAddr,
|
Source: clientAddr,
|
||||||
Destination: dest,
|
Destination: dest,
|
||||||
Inbound: this.meta,
|
Inbound: v.meta,
|
||||||
}
|
}
|
||||||
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, session)
|
v.transport(reader, writer, session)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) handleUDP(reader io.Reader, writer *v2io.BufferedWriter) error {
|
func (v *Server) handleUDP(reader io.Reader, writer *v2io.BufferedWriter) error {
|
||||||
response := protocol.NewSocks5Response()
|
response := protocol.NewSocks5Response()
|
||||||
response.Error = protocol.ErrorSuccess
|
response.Error = protocol.ErrorSuccess
|
||||||
|
|
||||||
udpAddr := this.udpAddress
|
udpAddr := v.udpAddress
|
||||||
|
|
||||||
response.Port = udpAddr.Port
|
response.Port = udpAddr.Port
|
||||||
switch udpAddr.Address.Family() {
|
switch udpAddr.Address.Family() {
|
||||||
|
@ -255,7 +255,7 @@ func (this *Server) handleUDP(reader io.Reader, writer *v2io.BufferedWriter) err
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// The TCP connection closes after this method returns. We need to wait until
|
// The TCP connection closes after v method returns. We need to wait until
|
||||||
// the client closes it.
|
// the client closes it.
|
||||||
// TODO: get notified from UDP part
|
// TODO: get notified from UDP part
|
||||||
<-time.After(5 * time.Minute)
|
<-time.After(5 * time.Minute)
|
||||||
|
@ -263,7 +263,7 @@ func (this *Server) handleUDP(reader io.Reader, writer *v2io.BufferedWriter) err
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) handleSocks4(clientAddr v2net.Destination, reader *v2io.BufferedReader, writer *v2io.BufferedWriter, auth protocol.Socks4AuthenticationRequest) error {
|
func (v *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
|
||||||
|
@ -285,15 +285,15 @@ func (this *Server) handleSocks4(clientAddr v2net.Destination, reader *v2io.Buff
|
||||||
session := &proxy.SessionInfo{
|
session := &proxy.SessionInfo{
|
||||||
Source: clientAddr,
|
Source: clientAddr,
|
||||||
Destination: dest,
|
Destination: dest,
|
||||||
Inbound: this.meta,
|
Inbound: v.meta,
|
||||||
}
|
}
|
||||||
log.Access(clientAddr, dest, log.AccessAccepted, "")
|
log.Access(clientAddr, dest, log.AccessAccepted, "")
|
||||||
this.transport(reader, writer, session)
|
v.transport(reader, writer, session)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) transport(reader io.Reader, writer io.Writer, session *proxy.SessionInfo) {
|
func (v *Server) transport(reader io.Reader, writer io.Writer, session *proxy.SessionInfo) {
|
||||||
ray := this.packetDispatcher.DispatchToOutbound(session)
|
ray := v.packetDispatcher.DispatchToOutbound(session)
|
||||||
input := ray.InboundInput()
|
input := ray.InboundInput()
|
||||||
output := ray.InboundOutput()
|
output := ray.InboundOutput()
|
||||||
|
|
||||||
|
@ -321,13 +321,13 @@ func (this *Server) transport(reader io.Reader, writer io.Writer, session *proxy
|
||||||
|
|
||||||
type ServerFactory struct{}
|
type ServerFactory struct{}
|
||||||
|
|
||||||
func (this *ServerFactory) StreamCapability() v2net.NetworkList {
|
func (v *ServerFactory) StreamCapability() v2net.NetworkList {
|
||||||
return v2net.NetworkList{
|
return v2net.NetworkList{
|
||||||
Network: []v2net.Network{v2net.Network_RawTCP},
|
Network: []v2net.Network{v2net.Network_RawTCP},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
func (v *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||||
return NewServer(rawConfig.(*ServerConfig), space, meta), nil
|
return NewServer(rawConfig.(*ServerConfig), space, meta), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,21 +9,21 @@ import (
|
||||||
"v2ray.com/core/transport/internet/udp"
|
"v2ray.com/core/transport/internet/udp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Server) listenUDP() error {
|
func (v *Server) listenUDP() error {
|
||||||
this.udpServer = udp.NewUDPServer(this.packetDispatcher)
|
v.udpServer = udp.NewUDPServer(v.packetDispatcher)
|
||||||
udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, udp.ListenOption{Callback: this.handleUDPPayload})
|
udpHub, err := udp.ListenUDP(v.meta.Address, v.meta.Port, udp.ListenOption{Callback: v.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 ", v.meta.Address, ":", v.meta.Port)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.udpMutex.Lock()
|
v.udpMutex.Lock()
|
||||||
this.udpAddress = v2net.UDPDestination(this.config.GetNetAddress(), this.meta.Port)
|
v.udpAddress = v2net.UDPDestination(v.config.GetNetAddress(), v.meta.Port)
|
||||||
this.udpHub = udpHub
|
v.udpHub = udpHub
|
||||||
this.udpMutex.Unlock()
|
v.udpMutex.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) handleUDPPayload(payload *alloc.Buffer, session *proxy.SessionInfo) {
|
func (v *Server) handleUDPPayload(payload *alloc.Buffer, session *proxy.SessionInfo) {
|
||||||
source := session.Source
|
source := session.Source
|
||||||
log.Info("Socks: Client UDP connection from ", source)
|
log.Info("Socks: Client UDP connection from ", source)
|
||||||
request, err := protocol.ReadUDPRequest(payload.Value)
|
request, err := protocol.ReadUDPRequest(payload.Value)
|
||||||
|
@ -46,7 +46,7 @@ func (this *Server) handleUDPPayload(payload *alloc.Buffer, session *proxy.Sessi
|
||||||
|
|
||||||
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(&proxy.SessionInfo{Source: source, Destination: request.Destination(), Inbound: this.meta}, request.Data, func(destination v2net.Destination, payload *alloc.Buffer) {
|
v.udpServer.Dispatch(&proxy.SessionInfo{Source: source, Destination: request.Destination(), Inbound: v.meta}, 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,
|
||||||
|
@ -58,13 +58,13 @@ func (this *Server) handleUDPPayload(payload *alloc.Buffer, session *proxy.Sessi
|
||||||
udpMessage := alloc.NewLocalBuffer(2048).Clear()
|
udpMessage := alloc.NewLocalBuffer(2048).Clear()
|
||||||
response.Write(udpMessage)
|
response.Write(udpMessage)
|
||||||
|
|
||||||
this.udpMutex.RLock()
|
v.udpMutex.RLock()
|
||||||
if !this.accepting {
|
if !v.accepting {
|
||||||
this.udpMutex.RUnlock()
|
v.udpMutex.RUnlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nBytes, err := this.udpHub.WriteTo(udpMessage.Value, destination)
|
nBytes, err := v.udpHub.WriteTo(udpMessage.Value, destination)
|
||||||
this.udpMutex.RUnlock()
|
v.udpMutex.RUnlock()
|
||||||
udpMessage.Release()
|
udpMessage.Release()
|
||||||
response.Data.Release()
|
response.Data.Release()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -18,20 +18,20 @@ type InboundConnectionHandler struct {
|
||||||
ConnOutput io.Writer
|
ConnOutput io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundConnectionHandler) Start() error {
|
func (v *InboundConnectionHandler) Start() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundConnectionHandler) Port() v2net.Port {
|
func (v *InboundConnectionHandler) Port() v2net.Port {
|
||||||
return this.ListeningPort
|
return v.ListeningPort
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundConnectionHandler) Close() {
|
func (v *InboundConnectionHandler) Close() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InboundConnectionHandler) Communicate(destination v2net.Destination) error {
|
func (v *InboundConnectionHandler) Communicate(destination v2net.Destination) error {
|
||||||
ray := this.PacketDispatcher.DispatchToOutbound(&proxy.SessionInfo{
|
ray := v.PacketDispatcher.DispatchToOutbound(&proxy.SessionInfo{
|
||||||
Source: v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(0)),
|
Source: v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(0)),
|
||||||
Destination: destination,
|
Destination: destination,
|
||||||
Inbound: &proxy.InboundHandlerMeta{
|
Inbound: &proxy.InboundHandlerMeta{
|
||||||
|
@ -49,7 +49,7 @@ func (this *InboundConnectionHandler) Communicate(destination v2net.Destination)
|
||||||
writeFinish.Lock()
|
writeFinish.Lock()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
v2reader := v2io.NewAdaptiveReader(this.ConnInput)
|
v2reader := v2io.NewAdaptiveReader(v.ConnInput)
|
||||||
defer v2reader.Release()
|
defer v2reader.Release()
|
||||||
|
|
||||||
v2io.Pipe(v2reader, input)
|
v2io.Pipe(v2reader, input)
|
||||||
|
@ -58,7 +58,7 @@ func (this *InboundConnectionHandler) Communicate(destination v2net.Destination)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
v2writer := v2io.NewAdaptiveWriter(this.ConnOutput)
|
v2writer := v2io.NewAdaptiveWriter(v.ConnOutput)
|
||||||
defer v2writer.Release()
|
defer v2writer.Release()
|
||||||
|
|
||||||
v2io.Pipe(output, v2writer)
|
v2io.Pipe(output, v2writer)
|
||||||
|
|
|
@ -18,13 +18,13 @@ type OutboundConnectionHandler struct {
|
||||||
ConnOutput io.Writer
|
ConnOutput io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *OutboundConnectionHandler) Dispatch(destination v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
|
func (v *OutboundConnectionHandler) Dispatch(destination v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
|
||||||
input := ray.OutboundInput()
|
input := ray.OutboundInput()
|
||||||
output := ray.OutboundOutput()
|
output := ray.OutboundOutput()
|
||||||
|
|
||||||
this.Destination = destination
|
v.Destination = destination
|
||||||
if !payload.IsEmpty() {
|
if !payload.IsEmpty() {
|
||||||
this.ConnOutput.Write(payload.Value)
|
v.ConnOutput.Write(payload.Value)
|
||||||
}
|
}
|
||||||
payload.Release()
|
payload.Release()
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ func (this *OutboundConnectionHandler) Dispatch(destination v2net.Destination, p
|
||||||
writeFinish.Lock()
|
writeFinish.Lock()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
v2writer := v2io.NewAdaptiveWriter(this.ConnOutput)
|
v2writer := v2io.NewAdaptiveWriter(v.ConnOutput)
|
||||||
defer v2writer.Release()
|
defer v2writer.Release()
|
||||||
|
|
||||||
v2io.Pipe(input, v2writer)
|
v2io.Pipe(input, v2writer)
|
||||||
|
@ -43,7 +43,7 @@ func (this *OutboundConnectionHandler) Dispatch(destination v2net.Destination, p
|
||||||
|
|
||||||
writeFinish.Lock()
|
writeFinish.Lock()
|
||||||
|
|
||||||
v2reader := v2io.NewAdaptiveReader(this.ConnInput)
|
v2reader := v2io.NewAdaptiveReader(v.ConnInput)
|
||||||
defer v2reader.Release()
|
defer v2reader.Release()
|
||||||
|
|
||||||
v2io.Pipe(v2reader, output)
|
v2io.Pipe(v2reader, output)
|
||||||
|
@ -52,6 +52,6 @@ func (this *OutboundConnectionHandler) Dispatch(destination v2net.Destination, p
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *OutboundConnectionHandler) Create(space app.Space, config interface{}, sendThrough v2net.Address) (proxy.OutboundHandler, error) {
|
func (v *OutboundConnectionHandler) Create(space app.Space, config interface{}, sendThrough v2net.Address) (proxy.OutboundHandler, error) {
|
||||||
return this, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,24 +12,24 @@ type InternalAccount struct {
|
||||||
AlterIDs []*protocol.ID
|
AlterIDs []*protocol.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InternalAccount) AnyValidID() *protocol.ID {
|
func (v *InternalAccount) AnyValidID() *protocol.ID {
|
||||||
if len(this.AlterIDs) == 0 {
|
if len(v.AlterIDs) == 0 {
|
||||||
return this.ID
|
return v.ID
|
||||||
}
|
}
|
||||||
return this.AlterIDs[dice.Roll(len(this.AlterIDs))]
|
return v.AlterIDs[dice.Roll(len(v.AlterIDs))]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *InternalAccount) Equals(account protocol.Account) bool {
|
func (v *InternalAccount) Equals(account protocol.Account) bool {
|
||||||
vmessAccount, ok := account.(*InternalAccount)
|
vmessAccount, ok := account.(*InternalAccount)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// TODO: handle AlterIds difference
|
// TODO: handle AlterIds difference
|
||||||
return this.ID.Equals(vmessAccount.ID)
|
return v.ID.Equals(vmessAccount.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Account) AsAccount() (protocol.Account, error) {
|
func (v *Account) AsAccount() (protocol.Account, error) {
|
||||||
id, err := uuid.ParseString(this.Id)
|
id, err := uuid.ParseString(v.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("VMess: Failed to parse ID: ", err)
|
log.Error("VMess: Failed to parse ID: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -37,6 +37,6 @@ func (this *Account) AsAccount() (protocol.Account, error) {
|
||||||
protoId := protocol.NewID(id)
|
protoId := protocol.NewID(id)
|
||||||
return &InternalAccount{
|
return &InternalAccount{
|
||||||
ID: protoId,
|
ID: protoId,
|
||||||
AlterIDs: protocol.NewAlterIDs(protoId, uint16(this.AlterId)),
|
AlterIDs: protocol.NewAlterIDs(protoId, uint16(v.AlterId)),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,22 +49,22 @@ func NewClientSession(idHash protocol.IDHash) *ClientSession {
|
||||||
return session
|
return session
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writer io.Writer) {
|
func (v *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writer io.Writer) {
|
||||||
timestamp := protocol.NewTimestampGenerator(protocol.NowTime(), 30)()
|
timestamp := protocol.NewTimestampGenerator(protocol.NowTime(), 30)()
|
||||||
account, err := header.User.GetTypedAccount()
|
account, err := header.User.GetTypedAccount()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("VMess: Failed to get user account: ", err)
|
log.Error("VMess: Failed to get user account: ", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
idHash := this.idHash(account.(*vmess.InternalAccount).AnyValidID().Bytes())
|
idHash := v.idHash(account.(*vmess.InternalAccount).AnyValidID().Bytes())
|
||||||
idHash.Write(timestamp.Bytes(nil))
|
idHash.Write(timestamp.Bytes(nil))
|
||||||
writer.Write(idHash.Sum(nil))
|
writer.Write(idHash.Sum(nil))
|
||||||
|
|
||||||
buffer := make([]byte, 0, 512)
|
buffer := make([]byte, 0, 512)
|
||||||
buffer = append(buffer, Version)
|
buffer = append(buffer, Version)
|
||||||
buffer = append(buffer, this.requestBodyIV...)
|
buffer = append(buffer, v.requestBodyIV...)
|
||||||
buffer = append(buffer, this.requestBodyKey...)
|
buffer = append(buffer, v.requestBodyKey...)
|
||||||
buffer = append(buffer, this.responseHeader, byte(header.Option), byte(0), byte(0), byte(header.Command))
|
buffer = append(buffer, v.responseHeader, byte(header.Option), byte(0), byte(0), byte(header.Command))
|
||||||
buffer = header.Port.Bytes(buffer)
|
buffer = header.Port.Bytes(buffer)
|
||||||
|
|
||||||
switch header.Address.Family() {
|
switch header.Address.Family() {
|
||||||
|
@ -94,25 +94,25 @@ func (this *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, w
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ClientSession) EncodeRequestBody(writer io.Writer) io.Writer {
|
func (v *ClientSession) EncodeRequestBody(writer io.Writer) io.Writer {
|
||||||
aesStream := crypto.NewAesEncryptionStream(this.requestBodyKey, this.requestBodyIV)
|
aesStream := crypto.NewAesEncryptionStream(v.requestBodyKey, v.requestBodyIV)
|
||||||
return crypto.NewCryptionWriter(aesStream, writer)
|
return crypto.NewCryptionWriter(aesStream, writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.ResponseHeader, error) {
|
func (v *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.ResponseHeader, error) {
|
||||||
aesStream := crypto.NewAesDecryptionStream(this.responseBodyKey, this.responseBodyIV)
|
aesStream := crypto.NewAesDecryptionStream(v.responseBodyKey, v.responseBodyIV)
|
||||||
this.responseReader = crypto.NewCryptionReader(aesStream, reader)
|
v.responseReader = crypto.NewCryptionReader(aesStream, reader)
|
||||||
|
|
||||||
buffer := make([]byte, 256)
|
buffer := make([]byte, 256)
|
||||||
|
|
||||||
_, err := io.ReadFull(this.responseReader, buffer[:4])
|
_, err := io.ReadFull(v.responseReader, buffer[:4])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Raw: Failed to read response header: ", err)
|
log.Info("Raw: Failed to read response header: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if buffer[0] != this.responseHeader {
|
if buffer[0] != v.responseHeader {
|
||||||
return nil, fmt.Errorf("VMess|Client: Unexpected response header. Expecting %d but actually %d", this.responseHeader, buffer[0])
|
return nil, fmt.Errorf("VMess|Client: Unexpected response header. Expecting %d but actually %d", v.responseHeader, buffer[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
header := &protocol.ResponseHeader{
|
header := &protocol.ResponseHeader{
|
||||||
|
@ -122,7 +122,7 @@ func (this *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.Res
|
||||||
if buffer[2] != 0 {
|
if buffer[2] != 0 {
|
||||||
cmdId := buffer[2]
|
cmdId := buffer[2]
|
||||||
dataLen := int(buffer[3])
|
dataLen := int(buffer[3])
|
||||||
_, err := io.ReadFull(this.responseReader, buffer[:dataLen])
|
_, err := io.ReadFull(v.responseReader, buffer[:dataLen])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Raw: Failed to read response command: ", err)
|
log.Info("Raw: Failed to read response command: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -137,6 +137,6 @@ func (this *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.Res
|
||||||
return header, nil
|
return header, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ClientSession) DecodeResponseBody(reader io.Reader) io.Reader {
|
func (v *ClientSession) DecodeResponseBody(reader io.Reader) io.Reader {
|
||||||
return this.responseReader
|
return v.responseReader
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ type CommandFactory interface {
|
||||||
type CommandSwitchAccountFactory struct {
|
type CommandSwitchAccountFactory struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *CommandSwitchAccountFactory) Marshal(command interface{}, writer io.Writer) error {
|
func (v *CommandSwitchAccountFactory) Marshal(command interface{}, writer io.Writer) error {
|
||||||
cmd, ok := command.(*protocol.CommandSwitchAccount)
|
cmd, ok := command.(*protocol.CommandSwitchAccount)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrCommandTypeMismatch
|
return ErrCommandTypeMismatch
|
||||||
|
@ -107,7 +107,7 @@ func (this *CommandSwitchAccountFactory) Marshal(command interface{}, writer io.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *CommandSwitchAccountFactory) Unmarshal(data []byte) (interface{}, error) {
|
func (v *CommandSwitchAccountFactory) Unmarshal(data []byte) (interface{}, error) {
|
||||||
cmd := new(protocol.CommandSwitchAccount)
|
cmd := new(protocol.CommandSwitchAccount)
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.")
|
return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.")
|
||||||
|
|
|
@ -32,16 +32,16 @@ func NewServerSession(validator protocol.UserValidator) *ServerSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release implements common.Releaseable.
|
// Release implements common.Releaseable.
|
||||||
func (this *ServerSession) Release() {
|
func (v *ServerSession) Release() {
|
||||||
this.userValidator = nil
|
v.userValidator = nil
|
||||||
this.requestBodyIV = nil
|
v.requestBodyIV = nil
|
||||||
this.requestBodyKey = nil
|
v.requestBodyKey = nil
|
||||||
this.responseBodyIV = nil
|
v.responseBodyIV = nil
|
||||||
this.responseBodyKey = nil
|
v.responseBodyKey = nil
|
||||||
this.responseWriter = nil
|
v.responseWriter = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.RequestHeader, error) {
|
func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.RequestHeader, error) {
|
||||||
buffer := make([]byte, 512)
|
buffer := make([]byte, 512)
|
||||||
|
|
||||||
_, err := io.ReadFull(reader, buffer[:protocol.IDBytesLen])
|
_, err := io.ReadFull(reader, buffer[:protocol.IDBytesLen])
|
||||||
|
@ -50,7 +50,7 @@ func (this *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Requ
|
||||||
return nil, io.EOF
|
return nil, io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
user, timestamp, valid := this.userValidator.Get(buffer[:protocol.IDBytesLen])
|
user, timestamp, valid := v.userValidator.Get(buffer[:protocol.IDBytesLen])
|
||||||
if !valid {
|
if !valid {
|
||||||
return nil, protocol.ErrInvalidUser
|
return nil, protocol.ErrInvalidUser
|
||||||
}
|
}
|
||||||
|
@ -82,9 +82,9 @@ func (this *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Requ
|
||||||
return nil, protocol.ErrInvalidVersion
|
return nil, protocol.ErrInvalidVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
this.requestBodyIV = append([]byte(nil), buffer[1:17]...) // 16 bytes
|
v.requestBodyIV = append([]byte(nil), buffer[1:17]...) // 16 bytes
|
||||||
this.requestBodyKey = append([]byte(nil), buffer[17:33]...) // 16 bytes
|
v.requestBodyKey = append([]byte(nil), buffer[17:33]...) // 16 bytes
|
||||||
this.responseHeader = buffer[33] // 1 byte
|
v.responseHeader = buffer[33] // 1 byte
|
||||||
request.Option = protocol.RequestOption(buffer[34]) // 1 byte + 2 bytes reserved
|
request.Option = protocol.RequestOption(buffer[34]) // 1 byte + 2 bytes reserved
|
||||||
request.Command = protocol.RequestCommand(buffer[37])
|
request.Command = protocol.RequestCommand(buffer[37])
|
||||||
|
|
||||||
|
@ -139,28 +139,28 @@ func (this *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Requ
|
||||||
return request, nil
|
return request, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerSession) DecodeRequestBody(reader io.Reader) io.Reader {
|
func (v *ServerSession) DecodeRequestBody(reader io.Reader) io.Reader {
|
||||||
aesStream := crypto.NewAesDecryptionStream(this.requestBodyKey, this.requestBodyIV)
|
aesStream := crypto.NewAesDecryptionStream(v.requestBodyKey, v.requestBodyIV)
|
||||||
return crypto.NewCryptionReader(aesStream, reader)
|
return crypto.NewCryptionReader(aesStream, reader)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerSession) EncodeResponseHeader(header *protocol.ResponseHeader, writer io.Writer) {
|
func (v *ServerSession) EncodeResponseHeader(header *protocol.ResponseHeader, writer io.Writer) {
|
||||||
responseBodyKey := md5.Sum(this.requestBodyKey)
|
responseBodyKey := md5.Sum(v.requestBodyKey)
|
||||||
responseBodyIV := md5.Sum(this.requestBodyIV)
|
responseBodyIV := md5.Sum(v.requestBodyIV)
|
||||||
this.responseBodyKey = responseBodyKey[:]
|
v.responseBodyKey = responseBodyKey[:]
|
||||||
this.responseBodyIV = responseBodyIV[:]
|
v.responseBodyIV = responseBodyIV[:]
|
||||||
|
|
||||||
aesStream := crypto.NewAesEncryptionStream(this.responseBodyKey, this.responseBodyIV)
|
aesStream := crypto.NewAesEncryptionStream(v.responseBodyKey, v.responseBodyIV)
|
||||||
encryptionWriter := crypto.NewCryptionWriter(aesStream, writer)
|
encryptionWriter := crypto.NewCryptionWriter(aesStream, writer)
|
||||||
this.responseWriter = encryptionWriter
|
v.responseWriter = encryptionWriter
|
||||||
|
|
||||||
encryptionWriter.Write([]byte{this.responseHeader, byte(header.Option)})
|
encryptionWriter.Write([]byte{v.responseHeader, byte(header.Option)})
|
||||||
err := MarshalCommand(header.Command, encryptionWriter)
|
err := MarshalCommand(header.Command, encryptionWriter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
encryptionWriter.Write([]byte{0x00, 0x00})
|
encryptionWriter.Write([]byte{0x00, 0x00})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerSession) EncodeResponseBody(writer io.Writer) io.Writer {
|
func (v *ServerSession) EncodeResponseBody(writer io.Writer) io.Writer {
|
||||||
return this.responseWriter
|
return v.responseWriter
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,11 @@ import (
|
||||||
"v2ray.com/core/proxy/vmess"
|
"v2ray.com/core/proxy/vmess"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *VMessInboundHandler) generateCommand(request *protocol.RequestHeader) protocol.ResponseCommand {
|
func (v *VMessInboundHandler) generateCommand(request *protocol.RequestHeader) protocol.ResponseCommand {
|
||||||
if this.detours != nil {
|
if v.detours != nil {
|
||||||
tag := this.detours.To
|
tag := v.detours.To
|
||||||
if this.inboundHandlerManager != nil {
|
if v.inboundHandlerManager != nil {
|
||||||
handler, availableMin := this.inboundHandlerManager.GetHandler(tag)
|
handler, availableMin := v.inboundHandlerManager.GetHandler(tag)
|
||||||
inboundHandler, ok := handler.(*VMessInboundHandler)
|
inboundHandler, ok := handler.(*VMessInboundHandler)
|
||||||
if ok {
|
if ok {
|
||||||
if availableMin > 255 {
|
if availableMin > 255 {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package inbound
|
package inbound
|
||||||
|
|
||||||
func (this *Config) GetDefaultValue() *DefaultConfig {
|
func (v *Config) GetDefaultValue() *DefaultConfig {
|
||||||
if this.GetDefault() == nil {
|
if v.GetDefault() == nil {
|
||||||
return &DefaultConfig{
|
return &DefaultConfig{
|
||||||
AlterId: 32,
|
AlterId: 32,
|
||||||
Level: 0,
|
Level: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.Default
|
return v.Default
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,28 +42,28 @@ func NewUserByEmail(users []*protocol.User, config *DefaultConfig) *userByEmail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *userByEmail) Get(email string) (*protocol.User, bool) {
|
func (v *userByEmail) Get(email string) (*protocol.User, bool) {
|
||||||
var user *protocol.User
|
var user *protocol.User
|
||||||
var found bool
|
var found bool
|
||||||
this.RLock()
|
v.RLock()
|
||||||
user, found = this.cache[email]
|
user, found = v.cache[email]
|
||||||
this.RUnlock()
|
v.RUnlock()
|
||||||
if !found {
|
if !found {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
user, found = this.cache[email]
|
user, found = v.cache[email]
|
||||||
if !found {
|
if !found {
|
||||||
account := &vmess.Account{
|
account := &vmess.Account{
|
||||||
Id: uuid.New().String(),
|
Id: uuid.New().String(),
|
||||||
AlterId: uint32(this.defaultAlterIDs),
|
AlterId: uint32(v.defaultAlterIDs),
|
||||||
}
|
}
|
||||||
user = &protocol.User{
|
user = &protocol.User{
|
||||||
Level: this.defaultLevel,
|
Level: v.defaultLevel,
|
||||||
Email: email,
|
Email: email,
|
||||||
Account: loader.NewTypedSettings(account),
|
Account: loader.NewTypedSettings(account),
|
||||||
}
|
}
|
||||||
this.cache[email] = user
|
v.cache[email] = user
|
||||||
}
|
}
|
||||||
this.Unlock()
|
v.Unlock()
|
||||||
}
|
}
|
||||||
return user, found
|
return user, found
|
||||||
}
|
}
|
||||||
|
@ -81,58 +81,58 @@ type VMessInboundHandler struct {
|
||||||
meta *proxy.InboundHandlerMeta
|
meta *proxy.InboundHandlerMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *VMessInboundHandler) Port() v2net.Port {
|
func (v *VMessInboundHandler) Port() v2net.Port {
|
||||||
return this.meta.Port
|
return v.meta.Port
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *VMessInboundHandler) Close() {
|
func (v *VMessInboundHandler) Close() {
|
||||||
this.accepting = false
|
v.accepting = false
|
||||||
if this.listener != nil {
|
if v.listener != nil {
|
||||||
this.Lock()
|
v.Lock()
|
||||||
this.listener.Close()
|
v.listener.Close()
|
||||||
this.listener = nil
|
v.listener = nil
|
||||||
this.clients.Release()
|
v.clients.Release()
|
||||||
this.clients = nil
|
v.clients = nil
|
||||||
this.Unlock()
|
v.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *VMessInboundHandler) GetUser(email string) *protocol.User {
|
func (v *VMessInboundHandler) GetUser(email string) *protocol.User {
|
||||||
this.RLock()
|
v.RLock()
|
||||||
defer this.RUnlock()
|
defer v.RUnlock()
|
||||||
|
|
||||||
if !this.accepting {
|
if !v.accepting {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
user, existing := this.usersByEmail.Get(email)
|
user, existing := v.usersByEmail.Get(email)
|
||||||
if !existing {
|
if !existing {
|
||||||
this.clients.Add(user)
|
v.clients.Add(user)
|
||||||
}
|
}
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *VMessInboundHandler) Start() error {
|
func (v *VMessInboundHandler) Start() error {
|
||||||
if this.accepting {
|
if v.accepting {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpListener, err := internet.ListenTCP(this.meta.Address, this.meta.Port, this.HandleConnection, this.meta.StreamSettings)
|
tcpListener, err := internet.ListenTCP(v.meta.Address, v.meta.Port, v.HandleConnection, v.meta.StreamSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("VMess|Inbound: Unable to listen tcp ", this.meta.Address, ":", this.meta.Port, ": ", err)
|
log.Error("VMess|Inbound: Unable to listen tcp ", v.meta.Address, ":", v.meta.Port, ": ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.accepting = true
|
v.accepting = true
|
||||||
this.Lock()
|
v.Lock()
|
||||||
this.listener = tcpListener
|
v.listener = tcpListener
|
||||||
this.Unlock()
|
v.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *VMessInboundHandler) HandleConnection(connection internet.Connection) {
|
func (v *VMessInboundHandler) HandleConnection(connection internet.Connection) {
|
||||||
defer connection.Close()
|
defer connection.Close()
|
||||||
|
|
||||||
if !this.accepting {
|
if !v.accepting {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,16 +142,16 @@ func (this *VMessInboundHandler) HandleConnection(connection internet.Connection
|
||||||
reader := v2io.NewBufferedReader(connReader)
|
reader := v2io.NewBufferedReader(connReader)
|
||||||
defer reader.Release()
|
defer reader.Release()
|
||||||
|
|
||||||
this.RLock()
|
v.RLock()
|
||||||
if !this.accepting {
|
if !v.accepting {
|
||||||
this.RUnlock()
|
v.RUnlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
session := encoding.NewServerSession(this.clients)
|
session := encoding.NewServerSession(v.clients)
|
||||||
defer session.Release()
|
defer session.Release()
|
||||||
|
|
||||||
request, err := session.DecodeRequestHeader(reader)
|
request, err := session.DecodeRequestHeader(reader)
|
||||||
this.RUnlock()
|
v.RUnlock()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
|
@ -166,11 +166,11 @@ 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(&proxy.SessionInfo{
|
ray := v.packetDispatcher.DispatchToOutbound(&proxy.SessionInfo{
|
||||||
Source: v2net.DestinationFromAddr(connection.RemoteAddr()),
|
Source: v2net.DestinationFromAddr(connection.RemoteAddr()),
|
||||||
Destination: request.Destination(),
|
Destination: request.Destination(),
|
||||||
User: request.User,
|
User: request.User,
|
||||||
Inbound: this.meta,
|
Inbound: v.meta,
|
||||||
})
|
})
|
||||||
input := ray.InboundInput()
|
input := ray.InboundInput()
|
||||||
output := ray.InboundOutput()
|
output := ray.InboundOutput()
|
||||||
|
@ -205,7 +205,7 @@ func (this *VMessInboundHandler) HandleConnection(connection internet.Connection
|
||||||
defer writer.Release()
|
defer writer.Release()
|
||||||
|
|
||||||
response := &protocol.ResponseHeader{
|
response := &protocol.ResponseHeader{
|
||||||
Command: this.generateCommand(request),
|
Command: v.generateCommand(request),
|
||||||
}
|
}
|
||||||
|
|
||||||
if connection.Reusable() {
|
if connection.Reusable() {
|
||||||
|
@ -247,13 +247,13 @@ func (this *VMessInboundHandler) HandleConnection(connection internet.Connection
|
||||||
|
|
||||||
type Factory struct{}
|
type Factory struct{}
|
||||||
|
|
||||||
func (this *Factory) StreamCapability() v2net.NetworkList {
|
func (v *Factory) StreamCapability() v2net.NetworkList {
|
||||||
return v2net.NetworkList{
|
return v2net.NetworkList{
|
||||||
Network: []v2net.Network{v2net.Network_TCP, v2net.Network_KCP, v2net.Network_WebSocket},
|
Network: []v2net.Network{v2net.Network_TCP, v2net.Network_KCP, v2net.Network_WebSocket},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
func (v *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||||
if !space.HasApp(dispatcher.APP_ID) {
|
if !space.HasApp(dispatcher.APP_ID) {
|
||||||
return nil, common.ErrBadConfiguration
|
return nil, common.ErrBadConfiguration
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,12 @@ func NewValidator(expectedAuth uint32) *Validator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Validator) Consume(b []byte) {
|
func (v *Validator) Consume(b []byte) {
|
||||||
this.actualAuth.Write(b)
|
v.actualAuth.Write(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Validator) Validate() bool {
|
func (v *Validator) Validate() bool {
|
||||||
return this.actualAuth.Sum32() == this.expectedAuth
|
return v.actualAuth.Sum32() == v.expectedAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthChunkReader struct {
|
type AuthChunkReader struct {
|
||||||
|
@ -44,73 +44,73 @@ func NewAuthChunkReader(reader io.Reader) *AuthChunkReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AuthChunkReader) Read() (*alloc.Buffer, error) {
|
func (v *AuthChunkReader) Read() (*alloc.Buffer, error) {
|
||||||
var buffer *alloc.Buffer
|
var buffer *alloc.Buffer
|
||||||
if this.last != nil {
|
if v.last != nil {
|
||||||
buffer = this.last
|
buffer = v.last
|
||||||
this.last = nil
|
v.last = nil
|
||||||
} else {
|
} else {
|
||||||
buffer = alloc.NewBuffer().Clear()
|
buffer = alloc.NewBuffer().Clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.chunkLength == -1 {
|
if v.chunkLength == -1 {
|
||||||
for buffer.Len() < 6 {
|
for buffer.Len() < 6 {
|
||||||
_, err := buffer.FillFrom(this.reader)
|
_, err := buffer.FillFrom(v.reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, io.ErrUnexpectedEOF
|
return nil, io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
length := serial.BytesToUint16(buffer.Value[:2])
|
length := serial.BytesToUint16(buffer.Value[:2])
|
||||||
this.chunkLength = int(length) - 4
|
v.chunkLength = int(length) - 4
|
||||||
this.validator = NewValidator(serial.BytesToUint32(buffer.Value[2:6]))
|
v.validator = NewValidator(serial.BytesToUint32(buffer.Value[2:6]))
|
||||||
buffer.SliceFrom(6)
|
buffer.SliceFrom(6)
|
||||||
if buffer.Len() < this.chunkLength && this.chunkLength <= 2048 {
|
if buffer.Len() < v.chunkLength && v.chunkLength <= 2048 {
|
||||||
_, err := buffer.FillFrom(this.reader)
|
_, err := buffer.FillFrom(v.reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, io.ErrUnexpectedEOF
|
return nil, io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if buffer.Len() < this.chunkLength {
|
} else if buffer.Len() < v.chunkLength {
|
||||||
_, err := buffer.FillFrom(this.reader)
|
_, err := buffer.FillFrom(v.reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, io.ErrUnexpectedEOF
|
return nil, io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.chunkLength == 0 {
|
if v.chunkLength == 0 {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, io.EOF
|
return nil, io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
if buffer.Len() < this.chunkLength {
|
if buffer.Len() < v.chunkLength {
|
||||||
this.validator.Consume(buffer.Value)
|
v.validator.Consume(buffer.Value)
|
||||||
this.chunkLength -= buffer.Len()
|
v.chunkLength -= buffer.Len()
|
||||||
} else {
|
} else {
|
||||||
this.validator.Consume(buffer.Value[:this.chunkLength])
|
v.validator.Consume(buffer.Value[:v.chunkLength])
|
||||||
if !this.validator.Validate() {
|
if !v.validator.Validate() {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, errors.New("VMess|AuthChunkReader: Invalid auth.")
|
return nil, errors.New("VMess|AuthChunkReader: Invalid auth.")
|
||||||
}
|
}
|
||||||
leftLength := buffer.Len() - this.chunkLength
|
leftLength := buffer.Len() - v.chunkLength
|
||||||
if leftLength > 0 {
|
if leftLength > 0 {
|
||||||
this.last = alloc.NewBuffer().Clear()
|
v.last = alloc.NewBuffer().Clear()
|
||||||
this.last.Append(buffer.Value[this.chunkLength:])
|
v.last.Append(buffer.Value[v.chunkLength:])
|
||||||
buffer.Slice(0, this.chunkLength)
|
buffer.Slice(0, v.chunkLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.chunkLength = -1
|
v.chunkLength = -1
|
||||||
this.validator = nil
|
v.validator = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer, nil
|
return buffer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AuthChunkReader) Release() {
|
func (v *AuthChunkReader) Release() {
|
||||||
this.reader = nil
|
v.reader = nil
|
||||||
this.last.Release()
|
v.last.Release()
|
||||||
this.last = nil
|
v.last = nil
|
||||||
this.validator = nil
|
v.validator = nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,14 +17,14 @@ func NewAuthChunkWriter(writer v2io.Writer) *AuthChunkWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AuthChunkWriter) Write(buffer *alloc.Buffer) error {
|
func (v *AuthChunkWriter) Write(buffer *alloc.Buffer) error {
|
||||||
Authenticate(buffer)
|
Authenticate(buffer)
|
||||||
return this.writer.Write(buffer)
|
return v.writer.Write(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *AuthChunkWriter) Release() {
|
func (v *AuthChunkWriter) Release() {
|
||||||
this.writer.Release()
|
v.writer.Release()
|
||||||
this.writer = nil
|
v.writer = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Authenticate(buffer *alloc.Buffer) {
|
func Authenticate(buffer *alloc.Buffer) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"v2ray.com/core/proxy/vmess"
|
"v2ray.com/core/proxy/vmess"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *VMessOutboundHandler) handleSwitchAccount(cmd *protocol.CommandSwitchAccount) {
|
func (v *VMessOutboundHandler) handleSwitchAccount(cmd *protocol.CommandSwitchAccount) {
|
||||||
account := &vmess.Account{
|
account := &vmess.Account{
|
||||||
Id: cmd.ID.String(),
|
Id: cmd.ID.String(),
|
||||||
AlterId: uint32(cmd.AlterIds),
|
AlterId: uint32(cmd.AlterIds),
|
||||||
|
@ -22,16 +22,16 @@ func (this *VMessOutboundHandler) handleSwitchAccount(cmd *protocol.CommandSwitc
|
||||||
}
|
}
|
||||||
dest := v2net.TCPDestination(cmd.Host, cmd.Port)
|
dest := v2net.TCPDestination(cmd.Host, cmd.Port)
|
||||||
until := time.Now().Add(time.Duration(cmd.ValidMin) * time.Minute)
|
until := time.Now().Add(time.Duration(cmd.ValidMin) * time.Minute)
|
||||||
this.serverList.AddServer(protocol.NewServerSpec(dest, protocol.BeforeTime(until), user))
|
v.serverList.AddServer(protocol.NewServerSpec(dest, protocol.BeforeTime(until), user))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *VMessOutboundHandler) handleCommand(dest v2net.Destination, cmd protocol.ResponseCommand) {
|
func (v *VMessOutboundHandler) handleCommand(dest v2net.Destination, cmd protocol.ResponseCommand) {
|
||||||
switch typedCommand := cmd.(type) {
|
switch typedCommand := cmd.(type) {
|
||||||
case *protocol.CommandSwitchAccount:
|
case *protocol.CommandSwitchAccount:
|
||||||
if typedCommand.Host == nil {
|
if typedCommand.Host == nil {
|
||||||
typedCommand.Host = dest.Address
|
typedCommand.Host = dest.Address
|
||||||
}
|
}
|
||||||
this.handleSwitchAccount(typedCommand)
|
v.handleSwitchAccount(typedCommand)
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ type VMessOutboundHandler struct {
|
||||||
meta *proxy.OutboundHandlerMeta
|
meta *proxy.OutboundHandlerMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
|
func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
|
||||||
defer ray.OutboundInput().Release()
|
defer ray.OutboundInput().Release()
|
||||||
defer ray.OutboundOutput().Close()
|
defer ray.OutboundOutput().Close()
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ func (this *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *al
|
||||||
var conn internet.Connection
|
var conn internet.Connection
|
||||||
|
|
||||||
err := retry.ExponentialBackoff(5, 100).On(func() error {
|
err := retry.ExponentialBackoff(5, 100).On(func() error {
|
||||||
rec = this.serverPicker.PickServer()
|
rec = v.serverPicker.PickServer()
|
||||||
rawConn, err := internet.Dial(this.meta.Address, rec.Destination(), this.meta.GetDialerOptions())
|
rawConn, err := internet.Dial(v.meta.Address, rec.Destination(), v.meta.GetDialerOptions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -77,15 +77,15 @@ func (this *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *al
|
||||||
|
|
||||||
session := encoding.NewClientSession(protocol.DefaultIDHash)
|
session := encoding.NewClientSession(protocol.DefaultIDHash)
|
||||||
|
|
||||||
go this.handleRequest(session, conn, request, payload, input, &requestFinish)
|
go v.handleRequest(session, conn, request, payload, input, &requestFinish)
|
||||||
go this.handleResponse(session, conn, request, rec.Destination(), output, &responseFinish)
|
go v.handleResponse(session, conn, request, rec.Destination(), output, &responseFinish)
|
||||||
|
|
||||||
requestFinish.Lock()
|
requestFinish.Lock()
|
||||||
responseFinish.Lock()
|
responseFinish.Lock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *VMessOutboundHandler) handleRequest(session *encoding.ClientSession, conn internet.Connection, request *protocol.RequestHeader, payload *alloc.Buffer, input v2io.Reader, finish *sync.Mutex) {
|
func (v *VMessOutboundHandler) handleRequest(session *encoding.ClientSession, conn internet.Connection, request *protocol.RequestHeader, payload *alloc.Buffer, input v2io.Reader, finish *sync.Mutex) {
|
||||||
defer finish.Unlock()
|
defer finish.Unlock()
|
||||||
|
|
||||||
writer := v2io.NewBufferedWriter(conn)
|
writer := v2io.NewBufferedWriter(conn)
|
||||||
|
@ -120,7 +120,7 @@ func (this *VMessOutboundHandler) handleRequest(session *encoding.ClientSession,
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *VMessOutboundHandler) handleResponse(session *encoding.ClientSession, conn internet.Connection, request *protocol.RequestHeader, dest v2net.Destination, output v2io.Writer, finish *sync.Mutex) {
|
func (v *VMessOutboundHandler) handleResponse(session *encoding.ClientSession, conn internet.Connection, request *protocol.RequestHeader, dest v2net.Destination, output v2io.Writer, finish *sync.Mutex) {
|
||||||
defer finish.Unlock()
|
defer finish.Unlock()
|
||||||
|
|
||||||
reader := v2io.NewBufferedReader(conn)
|
reader := v2io.NewBufferedReader(conn)
|
||||||
|
@ -132,7 +132,7 @@ func (this *VMessOutboundHandler) handleResponse(session *encoding.ClientSession
|
||||||
log.Warning("VMess|Outbound: Failed to read response from ", request.Destination(), ": ", err)
|
log.Warning("VMess|Outbound: Failed to read response from ", request.Destination(), ": ", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
go this.handleCommand(dest, header.Command)
|
go v.handleCommand(dest, header.Command)
|
||||||
|
|
||||||
if !header.Option.Has(protocol.ResponseOptionConnectionReuse) {
|
if !header.Option.Has(protocol.ResponseOptionConnectionReuse) {
|
||||||
conn.SetReusable(false)
|
conn.SetReusable(false)
|
||||||
|
@ -158,13 +158,13 @@ func (this *VMessOutboundHandler) handleResponse(session *encoding.ClientSession
|
||||||
|
|
||||||
type Factory struct{}
|
type Factory struct{}
|
||||||
|
|
||||||
func (this *Factory) StreamCapability() v2net.NetworkList {
|
func (v *Factory) StreamCapability() v2net.NetworkList {
|
||||||
return v2net.NetworkList{
|
return v2net.NetworkList{
|
||||||
Network: []v2net.Network{v2net.Network_TCP, v2net.Network_KCP, v2net.Network_WebSocket},
|
Network: []v2net.Network{v2net.Network_TCP, v2net.Network_KCP, v2net.Network_WebSocket},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
func (v *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||||
vOutConfig := rawConfig.(*Config)
|
vOutConfig := rawConfig.(*Config)
|
||||||
|
|
||||||
serverList := protocol.NewServerList()
|
serverList := protocol.NewServerList()
|
||||||
|
|
|
@ -53,33 +53,33 @@ func NewTimedUserValidator(hasher protocol.IDHash) protocol.UserValidator {
|
||||||
return tus
|
return tus
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TimedUserValidator) Release() {
|
func (v *TimedUserValidator) Release() {
|
||||||
if !this.running {
|
if !v.running {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cancel.Cancel()
|
v.cancel.Cancel()
|
||||||
this.cancel.WaitForDone()
|
v.cancel.WaitForDone()
|
||||||
|
|
||||||
this.Lock()
|
v.Lock()
|
||||||
defer this.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
if !this.running {
|
if !v.running {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.running = false
|
v.running = false
|
||||||
this.validUsers = nil
|
v.validUsers = nil
|
||||||
this.userHash = nil
|
v.userHash = nil
|
||||||
this.ids = nil
|
v.ids = nil
|
||||||
this.hasher = nil
|
v.hasher = nil
|
||||||
this.cancel = nil
|
v.cancel = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TimedUserValidator) generateNewHashes(nowSec protocol.Timestamp, idx int, entry *idEntry) {
|
func (v *TimedUserValidator) generateNewHashes(nowSec protocol.Timestamp, idx int, entry *idEntry) {
|
||||||
var hashValue [16]byte
|
var hashValue [16]byte
|
||||||
var hashValueRemoval [16]byte
|
var hashValueRemoval [16]byte
|
||||||
idHash := this.hasher(entry.id.Bytes())
|
idHash := v.hasher(entry.id.Bytes())
|
||||||
for entry.lastSec <= nowSec {
|
for entry.lastSec <= nowSec {
|
||||||
idHash.Write(entry.lastSec.Bytes(nil))
|
idHash.Write(entry.lastSec.Bytes(nil))
|
||||||
idHash.Sum(hashValue[:0])
|
idHash.Sum(hashValue[:0])
|
||||||
|
@ -89,36 +89,36 @@ func (this *TimedUserValidator) generateNewHashes(nowSec protocol.Timestamp, idx
|
||||||
idHash.Sum(hashValueRemoval[:0])
|
idHash.Sum(hashValueRemoval[:0])
|
||||||
idHash.Reset()
|
idHash.Reset()
|
||||||
|
|
||||||
this.Lock()
|
v.Lock()
|
||||||
this.userHash[hashValue] = &indexTimePair{idx, entry.lastSec}
|
v.userHash[hashValue] = &indexTimePair{idx, entry.lastSec}
|
||||||
delete(this.userHash, hashValueRemoval)
|
delete(v.userHash, hashValueRemoval)
|
||||||
this.Unlock()
|
v.Unlock()
|
||||||
|
|
||||||
entry.lastSec++
|
entry.lastSec++
|
||||||
entry.lastSecRemoval++
|
entry.lastSecRemoval++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TimedUserValidator) updateUserHash(interval time.Duration) {
|
func (v *TimedUserValidator) updateUserHash(interval time.Duration) {
|
||||||
this.cancel.WaitThread()
|
v.cancel.WaitThread()
|
||||||
defer this.cancel.FinishThread()
|
defer v.cancel.FinishThread()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case now := <-time.After(interval):
|
case now := <-time.After(interval):
|
||||||
nowSec := protocol.Timestamp(now.Unix() + cacheDurationSec)
|
nowSec := protocol.Timestamp(now.Unix() + cacheDurationSec)
|
||||||
for _, entry := range this.ids {
|
for _, entry := range v.ids {
|
||||||
this.generateNewHashes(nowSec, entry.userIdx, entry)
|
v.generateNewHashes(nowSec, entry.userIdx, entry)
|
||||||
}
|
}
|
||||||
case <-this.cancel.WaitForCancel():
|
case <-v.cancel.WaitForCancel():
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TimedUserValidator) Add(user *protocol.User) error {
|
func (v *TimedUserValidator) Add(user *protocol.User) error {
|
||||||
idx := len(this.validUsers)
|
idx := len(v.validUsers)
|
||||||
this.validUsers = append(this.validUsers, user)
|
v.validUsers = append(v.validUsers, user)
|
||||||
rawAccount, err := user.GetTypedAccount()
|
rawAccount, err := user.GetTypedAccount()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -133,8 +133,8 @@ func (this *TimedUserValidator) Add(user *protocol.User) error {
|
||||||
lastSec: protocol.Timestamp(nowSec - cacheDurationSec),
|
lastSec: protocol.Timestamp(nowSec - cacheDurationSec),
|
||||||
lastSecRemoval: protocol.Timestamp(nowSec - cacheDurationSec*3),
|
lastSecRemoval: protocol.Timestamp(nowSec - cacheDurationSec*3),
|
||||||
}
|
}
|
||||||
this.generateNewHashes(protocol.Timestamp(nowSec+cacheDurationSec), idx, entry)
|
v.generateNewHashes(protocol.Timestamp(nowSec+cacheDurationSec), idx, entry)
|
||||||
this.ids = append(this.ids, entry)
|
v.ids = append(v.ids, entry)
|
||||||
for _, alterid := range account.AlterIDs {
|
for _, alterid := range account.AlterIDs {
|
||||||
entry := &idEntry{
|
entry := &idEntry{
|
||||||
id: alterid,
|
id: alterid,
|
||||||
|
@ -142,25 +142,25 @@ func (this *TimedUserValidator) Add(user *protocol.User) error {
|
||||||
lastSec: protocol.Timestamp(nowSec - cacheDurationSec),
|
lastSec: protocol.Timestamp(nowSec - cacheDurationSec),
|
||||||
lastSecRemoval: protocol.Timestamp(nowSec - cacheDurationSec*3),
|
lastSecRemoval: protocol.Timestamp(nowSec - cacheDurationSec*3),
|
||||||
}
|
}
|
||||||
this.generateNewHashes(protocol.Timestamp(nowSec+cacheDurationSec), idx, entry)
|
v.generateNewHashes(protocol.Timestamp(nowSec+cacheDurationSec), idx, entry)
|
||||||
this.ids = append(this.ids, entry)
|
v.ids = append(v.ids, entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TimedUserValidator) Get(userHash []byte) (*protocol.User, protocol.Timestamp, bool) {
|
func (v *TimedUserValidator) Get(userHash []byte) (*protocol.User, protocol.Timestamp, bool) {
|
||||||
defer this.RUnlock()
|
defer v.RUnlock()
|
||||||
this.RLock()
|
v.RLock()
|
||||||
|
|
||||||
if !this.running {
|
if !v.running {
|
||||||
return nil, 0, false
|
return nil, 0, false
|
||||||
}
|
}
|
||||||
var fixedSizeHash [16]byte
|
var fixedSizeHash [16]byte
|
||||||
copy(fixedSizeHash[:], userHash)
|
copy(fixedSizeHash[:], userHash)
|
||||||
pair, found := this.userHash[fixedSizeHash]
|
pair, found := v.userHash[fixedSizeHash]
|
||||||
if found {
|
if found {
|
||||||
return this.validUsers[pair.index], pair.timeSec, true
|
return v.validUsers[pair.index], pair.timeSec, true
|
||||||
}
|
}
|
||||||
return nil, 0, false
|
return nil, 0, false
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,11 @@ import (
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Assert) Address(value v2net.Address) *AddressSubject {
|
func (v *Assert) Address(value v2net.Address) *AddressSubject {
|
||||||
return &AddressSubject{
|
return &AddressSubject{
|
||||||
Subject: Subject{
|
Subject: Subject{
|
||||||
disp: value.String(),
|
disp: value.String(),
|
||||||
a: this,
|
a: v,
|
||||||
},
|
},
|
||||||
value: value,
|
value: value,
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@ type Assert struct {
|
||||||
t *testing.T
|
t *testing.T
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Assert) Fail(message string) {
|
func (v *Assert) Fail(message string) {
|
||||||
fmt.Println(decorate(message))
|
fmt.Println(decorate(message))
|
||||||
this.t.Fail()
|
v.t.Fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCaller() (string, int) {
|
func getCaller() (string, int) {
|
||||||
|
|
|
@ -5,11 +5,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Assert on a boolean variable.
|
// Assert on a boolean variable.
|
||||||
func (this *Assert) Bool(value bool) *BoolSubject {
|
func (v *Assert) Bool(value bool) *BoolSubject {
|
||||||
return &BoolSubject{
|
return &BoolSubject{
|
||||||
Subject: Subject{
|
Subject: Subject{
|
||||||
disp: strconv.FormatBool(value),
|
disp: strconv.FormatBool(value),
|
||||||
a: this,
|
a: v,
|
||||||
},
|
},
|
||||||
value: value,
|
value: value,
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,11 @@ import (
|
||||||
"v2ray.com/core/common/serial"
|
"v2ray.com/core/common/serial"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Assert) Byte(value byte) *ByteSubject {
|
func (v *Assert) Byte(value byte) *ByteSubject {
|
||||||
return &ByteSubject{
|
return &ByteSubject{
|
||||||
Subject: Subject{
|
Subject: Subject{
|
||||||
disp: serial.ByteToHexString(value),
|
disp: serial.ByteToHexString(value),
|
||||||
a: this,
|
a: v,
|
||||||
},
|
},
|
||||||
value: value,
|
value: value,
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,11 @@ import (
|
||||||
"v2ray.com/core/common/serial"
|
"v2ray.com/core/common/serial"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Assert) Bytes(value []byte) *BytesSubject {
|
func (v *Assert) Bytes(value []byte) *BytesSubject {
|
||||||
return &BytesSubject{
|
return &BytesSubject{
|
||||||
Subject: Subject{
|
Subject: Subject{
|
||||||
disp: serial.BytesToHexString(value),
|
disp: serial.BytesToHexString(value),
|
||||||
a: this,
|
a: v,
|
||||||
},
|
},
|
||||||
value: value,
|
value: value,
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,11 @@ import (
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Assert) Destination(value v2net.Destination) *DestinationSubject {
|
func (v *Assert) Destination(value v2net.Destination) *DestinationSubject {
|
||||||
return &DestinationSubject{
|
return &DestinationSubject{
|
||||||
Subject: Subject{
|
Subject: Subject{
|
||||||
disp: value.String(),
|
disp: value.String(),
|
||||||
a: this,
|
a: v,
|
||||||
},
|
},
|
||||||
value: value,
|
value: value,
|
||||||
}
|
}
|
||||||
|
@ -19,40 +19,40 @@ type DestinationSubject struct {
|
||||||
value v2net.Destination
|
value v2net.Destination
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DestinationSubject) IsTCP() {
|
func (v *DestinationSubject) IsTCP() {
|
||||||
if this.value.Network != v2net.Network_TCP {
|
if v.value.Network != v2net.Network_TCP {
|
||||||
this.Fail("is", "a TCP destination")
|
v.Fail("is", "a TCP destination")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DestinationSubject) IsNotTCP() {
|
func (v *DestinationSubject) IsNotTCP() {
|
||||||
if this.value.Network == v2net.Network_TCP {
|
if v.value.Network == v2net.Network_TCP {
|
||||||
this.Fail("is not", "a TCP destination")
|
v.Fail("is not", "a TCP destination")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DestinationSubject) IsUDP() {
|
func (v *DestinationSubject) IsUDP() {
|
||||||
if this.value.Network != v2net.Network_UDP {
|
if v.value.Network != v2net.Network_UDP {
|
||||||
this.Fail("is", "a UDP destination")
|
v.Fail("is", "a UDP destination")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DestinationSubject) IsNotUDP() {
|
func (v *DestinationSubject) IsNotUDP() {
|
||||||
if this.value.Network == v2net.Network_UDP {
|
if v.value.Network == v2net.Network_UDP {
|
||||||
this.Fail("is not", "a UDP destination")
|
v.Fail("is not", "a UDP destination")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DestinationSubject) EqualsString(another string) {
|
func (v *DestinationSubject) EqualsString(another string) {
|
||||||
if this.value.String() != another {
|
if v.value.String() != another {
|
||||||
this.Fail("not equals to string", another)
|
v.Fail("not equals to string", another)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DestinationSubject) HasAddress() *AddressSubject {
|
func (v *DestinationSubject) HasAddress() *AddressSubject {
|
||||||
return this.a.Address(this.value.Address)
|
return v.a.Address(v.value.Address)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DestinationSubject) HasPort() *PortSubject {
|
func (v *DestinationSubject) HasPort() *PortSubject {
|
||||||
return this.a.Port(this.value.Port)
|
return v.a.Port(v.value.Port)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package assert
|
package assert
|
||||||
|
|
||||||
func (this *Assert) Error(value error) *ErrorSubject {
|
func (v *Assert) Error(value error) *ErrorSubject {
|
||||||
valueStr := ""
|
valueStr := ""
|
||||||
if value != nil {
|
if value != nil {
|
||||||
valueStr = value.Error()
|
valueStr = value.Error()
|
||||||
}
|
}
|
||||||
return &ErrorSubject{
|
return &ErrorSubject{
|
||||||
Subject: Subject{
|
Subject: Subject{
|
||||||
a: this,
|
a: v,
|
||||||
disp: valueStr,
|
disp: valueStr,
|
||||||
},
|
},
|
||||||
value: value,
|
value: value,
|
||||||
|
|
|
@ -4,10 +4,10 @@ import (
|
||||||
"v2ray.com/core/common/serial"
|
"v2ray.com/core/common/serial"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Assert) Int64(value int64) *Int64Subject {
|
func (v *Assert) Int64(value int64) *Int64Subject {
|
||||||
return &Int64Subject{
|
return &Int64Subject{
|
||||||
Subject: Subject{
|
Subject: Subject{
|
||||||
a: this,
|
a: v,
|
||||||
disp: serial.Int64ToString(value),
|
disp: serial.Int64ToString(value),
|
||||||
},
|
},
|
||||||
value: value,
|
value: value,
|
||||||
|
|
|
@ -4,10 +4,10 @@ import (
|
||||||
"v2ray.com/core/common/serial"
|
"v2ray.com/core/common/serial"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Assert) Int(value int) *IntSubject {
|
func (v *Assert) Int(value int) *IntSubject {
|
||||||
return &IntSubject{
|
return &IntSubject{
|
||||||
Subject: Subject{
|
Subject: Subject{
|
||||||
a: this,
|
a: v,
|
||||||
disp: serial.IntToString(value),
|
disp: serial.IntToString(value),
|
||||||
},
|
},
|
||||||
value: value,
|
value: value,
|
||||||
|
|
|
@ -5,10 +5,10 @@ import (
|
||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Assert) IP(value net.IP) *IPSubject {
|
func (v *Assert) IP(value net.IP) *IPSubject {
|
||||||
return &IPSubject{
|
return &IPSubject{
|
||||||
Subject: Subject{
|
Subject: Subject{
|
||||||
a: this,
|
a: v,
|
||||||
disp: value.String(),
|
disp: value.String(),
|
||||||
},
|
},
|
||||||
value: value,
|
value: value,
|
||||||
|
|
|
@ -6,10 +6,10 @@ import (
|
||||||
"v2ray.com/core/common/serial"
|
"v2ray.com/core/common/serial"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Assert) Pointer(value interface{}) *PointerSubject {
|
func (v *Assert) Pointer(value interface{}) *PointerSubject {
|
||||||
return &PointerSubject{
|
return &PointerSubject{
|
||||||
Subject: Subject{
|
Subject: Subject{
|
||||||
a: this,
|
a: v,
|
||||||
disp: serial.PointerToString(value),
|
disp: serial.PointerToString(value),
|
||||||
},
|
},
|
||||||
value: value,
|
value: value,
|
||||||
|
|
|
@ -4,10 +4,10 @@ import (
|
||||||
v2net "v2ray.com/core/common/net"
|
v2net "v2ray.com/core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Assert) Port(value v2net.Port) *PortSubject {
|
func (v *Assert) Port(value v2net.Port) *PortSubject {
|
||||||
return &PortSubject{
|
return &PortSubject{
|
||||||
Subject: Subject{
|
Subject: Subject{
|
||||||
a: this,
|
a: v,
|
||||||
disp: value.String(),
|
disp: value.String(),
|
||||||
},
|
},
|
||||||
value: value,
|
value: value,
|
||||||
|
|
|
@ -4,10 +4,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Assert) String(value string) *StringSubject {
|
func (v *Assert) String(value string) *StringSubject {
|
||||||
return &StringSubject{
|
return &StringSubject{
|
||||||
Subject: Subject{
|
Subject: Subject{
|
||||||
a: this,
|
a: v,
|
||||||
disp: value,
|
disp: value,
|
||||||
},
|
},
|
||||||
value: value,
|
value: value,
|
||||||
|
|
|
@ -4,10 +4,10 @@ import (
|
||||||
"v2ray.com/core/common/serial"
|
"v2ray.com/core/common/serial"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Assert) Uint16(value uint16) *Uint16Subject {
|
func (v *Assert) Uint16(value uint16) *Uint16Subject {
|
||||||
return &Uint16Subject{
|
return &Uint16Subject{
|
||||||
Subject: Subject{
|
Subject: Subject{
|
||||||
a: this,
|
a: v,
|
||||||
disp: serial.Uint16ToString(value),
|
disp: serial.Uint16ToString(value),
|
||||||
},
|
},
|
||||||
value: value,
|
value: value,
|
||||||
|
|
|
@ -4,10 +4,10 @@ import (
|
||||||
"v2ray.com/core/common/serial"
|
"v2ray.com/core/common/serial"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Assert) Uint32(value uint32) *Uint32Subject {
|
func (v *Assert) Uint32(value uint32) *Uint32Subject {
|
||||||
return &Uint32Subject{
|
return &Uint32Subject{
|
||||||
Subject: Subject{
|
Subject: Subject{
|
||||||
a: this,
|
a: v,
|
||||||
disp: serial.Uint32ToString(value),
|
disp: serial.Uint32ToString(value),
|
||||||
},
|
},
|
||||||
value: value,
|
value: value,
|
||||||
|
|
|
@ -31,6 +31,6 @@ func (server *Server) Start() (v2net.Destination, error) {
|
||||||
return v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(server.Port)), nil
|
return v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(server.Port)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) Close() {
|
func (v *Server) Close() {
|
||||||
this.accepting = false
|
v.accepting = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ func (server *Server) handleConnection(conn net.Conn) {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Server) Close() {
|
func (v *Server) Close() {
|
||||||
this.accepting = false
|
v.accepting = false
|
||||||
this.listener.Close()
|
v.listener.Close()
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,10 @@ type BlackholeConfig struct {
|
||||||
Response json.RawMessage `json:"response"`
|
Response json.RawMessage `json:"response"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *BlackholeConfig) Build() (*loader.TypedSettings, error) {
|
func (v *BlackholeConfig) Build() (*loader.TypedSettings, error) {
|
||||||
config := new(blackhole.Config)
|
config := new(blackhole.Config)
|
||||||
if this.Response != nil {
|
if v.Response != nil {
|
||||||
response, _, err := configLoader.Load(this.Response)
|
response, _, err := configLoader.Load(v.Response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("Blackhole: Failed to parse response config: " + err.Error())
|
return nil, errors.New("Blackhole: Failed to parse response config: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,21 +17,21 @@ func NewStringList(raw []string) *StringList {
|
||||||
return &list
|
return &list
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this StringList) Len() int {
|
func (v StringList) Len() int {
|
||||||
return len(this)
|
return len(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *StringList) UnmarshalJSON(data []byte) error {
|
func (v *StringList) UnmarshalJSON(data []byte) error {
|
||||||
var strarray []string
|
var strarray []string
|
||||||
if err := json.Unmarshal(data, &strarray); err == nil {
|
if err := json.Unmarshal(data, &strarray); err == nil {
|
||||||
*this = *NewStringList(strarray)
|
*v = *NewStringList(strarray)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var rawstr string
|
var rawstr string
|
||||||
if err := json.Unmarshal(data, &rawstr); err == nil {
|
if err := json.Unmarshal(data, &rawstr); err == nil {
|
||||||
strlist := strings.Split(rawstr, ",")
|
strlist := strings.Split(rawstr, ",")
|
||||||
*this = *NewStringList(strlist)
|
*v = *NewStringList(strlist)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errors.New("Unknown format of a string list: " + string(data))
|
return errors.New("Unknown format of a string list: " + string(data))
|
||||||
|
@ -41,45 +41,45 @@ type Address struct {
|
||||||
v2net.Address
|
v2net.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Address) UnmarshalJSON(data []byte) error {
|
func (v *Address) UnmarshalJSON(data []byte) error {
|
||||||
var rawStr string
|
var rawStr string
|
||||||
if err := json.Unmarshal(data, &rawStr); err != nil {
|
if err := json.Unmarshal(data, &rawStr); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.Address = v2net.ParseAddress(rawStr)
|
v.Address = v2net.ParseAddress(rawStr)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Address) Build() *v2net.IPOrDomain {
|
func (v *Address) Build() *v2net.IPOrDomain {
|
||||||
if this.Family().IsDomain() {
|
if v.Family().IsDomain() {
|
||||||
return &v2net.IPOrDomain{
|
return &v2net.IPOrDomain{
|
||||||
Address: &v2net.IPOrDomain_Domain{
|
Address: &v2net.IPOrDomain_Domain{
|
||||||
Domain: this.Domain(),
|
Domain: v.Domain(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &v2net.IPOrDomain{
|
return &v2net.IPOrDomain{
|
||||||
Address: &v2net.IPOrDomain_Ip{
|
Address: &v2net.IPOrDomain_Ip{
|
||||||
Ip: []byte(this.IP()),
|
Ip: []byte(v.IP()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Network string
|
type Network string
|
||||||
|
|
||||||
func (this Network) Build() v2net.Network {
|
func (v Network) Build() v2net.Network {
|
||||||
return v2net.ParseNetwork(string(this))
|
return v2net.ParseNetwork(string(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
type NetworkList []Network
|
type NetworkList []Network
|
||||||
|
|
||||||
func (this *NetworkList) UnmarshalJSON(data []byte) error {
|
func (v *NetworkList) UnmarshalJSON(data []byte) error {
|
||||||
var strarray []Network
|
var strarray []Network
|
||||||
if err := json.Unmarshal(data, &strarray); err == nil {
|
if err := json.Unmarshal(data, &strarray); err == nil {
|
||||||
nl := NetworkList(strarray)
|
nl := NetworkList(strarray)
|
||||||
*this = nl
|
*v = nl
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,15 +90,15 @@ func (this *NetworkList) UnmarshalJSON(data []byte) error {
|
||||||
for idx, network := range strlist {
|
for idx, network := range strlist {
|
||||||
nl[idx] = Network(network)
|
nl[idx] = Network(network)
|
||||||
}
|
}
|
||||||
*this = nl
|
*v = nl
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errors.New("Unknown format of a string list: " + string(data))
|
return errors.New("Unknown format of a string list: " + string(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *NetworkList) Build() *v2net.NetworkList {
|
func (v *NetworkList) Build() *v2net.NetworkList {
|
||||||
list := new(v2net.NetworkList)
|
list := new(v2net.NetworkList)
|
||||||
for _, network := range *this {
|
for _, network := range *v {
|
||||||
list.Network = append(list.Network, network.Build())
|
list.Network = append(list.Network, network.Build())
|
||||||
}
|
}
|
||||||
return list
|
return list
|
||||||
|
@ -144,28 +144,28 @@ type PortRange struct {
|
||||||
To uint32
|
To uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *PortRange) Build() *v2net.PortRange {
|
func (v *PortRange) Build() *v2net.PortRange {
|
||||||
return &v2net.PortRange{
|
return &v2net.PortRange{
|
||||||
From: this.From,
|
From: v.From,
|
||||||
To: this.To,
|
To: v.To,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON
|
// UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON
|
||||||
func (this *PortRange) UnmarshalJSON(data []byte) error {
|
func (v *PortRange) UnmarshalJSON(data []byte) error {
|
||||||
port, err := parseIntPort(data)
|
port, err := parseIntPort(data)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
this.From = uint32(port)
|
v.From = uint32(port)
|
||||||
this.To = uint32(port)
|
v.To = uint32(port)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
from, to, err := parseStringPort(data)
|
from, to, err := parseStringPort(data)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
this.From = uint32(from)
|
v.From = uint32(from)
|
||||||
this.To = uint32(to)
|
v.To = uint32(to)
|
||||||
if this.From > this.To {
|
if v.From > v.To {
|
||||||
log.Error("Invalid port range ", this.From, " -> ", this.To)
|
log.Error("Invalid port range ", v.From, " -> ", v.To)
|
||||||
return v2net.ErrInvalidPortRange
|
return v2net.ErrInvalidPortRange
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -180,9 +180,9 @@ type User struct {
|
||||||
LevelByte byte `json:"level"`
|
LevelByte byte `json:"level"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *User) Build() *protocol.User {
|
func (v *User) Build() *protocol.User {
|
||||||
return &protocol.User{
|
return &protocol.User{
|
||||||
Email: this.EmailString,
|
Email: v.EmailString,
|
||||||
Level: uint32(this.LevelByte),
|
Level: uint32(v.LevelByte),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,10 @@ type DnsConfig struct {
|
||||||
Hosts map[string]*Address `json:"hosts"`
|
Hosts map[string]*Address `json:"hosts"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DnsConfig) Build() *dns.Config {
|
func (v *DnsConfig) Build() *dns.Config {
|
||||||
config := new(dns.Config)
|
config := new(dns.Config)
|
||||||
config.NameServers = make([]*v2net.Endpoint, len(this.Servers))
|
config.NameServers = make([]*v2net.Endpoint, len(v.Servers))
|
||||||
for idx, server := range this.Servers {
|
for idx, server := range v.Servers {
|
||||||
config.NameServers[idx] = &v2net.Endpoint{
|
config.NameServers[idx] = &v2net.Endpoint{
|
||||||
Network: v2net.Network_UDP,
|
Network: v2net.Network_UDP,
|
||||||
Address: server.Build(),
|
Address: server.Build(),
|
||||||
|
@ -21,9 +21,9 @@ func (this *DnsConfig) Build() *dns.Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.Hosts != nil {
|
if v.Hosts != nil {
|
||||||
config.Hosts = make(map[string]*v2net.IPOrDomain)
|
config.Hosts = make(map[string]*v2net.IPOrDomain)
|
||||||
for domain, ip := range this.Hosts {
|
for domain, ip := range v.Hosts {
|
||||||
config.Hosts[domain] = ip.Build()
|
config.Hosts[domain] = ip.Build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,14 @@ type DokodemoConfig struct {
|
||||||
Redirect bool `json:"followRedirect"`
|
Redirect bool `json:"followRedirect"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DokodemoConfig) Build() (*loader.TypedSettings, error) {
|
func (v *DokodemoConfig) Build() (*loader.TypedSettings, error) {
|
||||||
config := new(dokodemo.Config)
|
config := new(dokodemo.Config)
|
||||||
if this.Host != nil {
|
if v.Host != nil {
|
||||||
config.Address = this.Host.Build()
|
config.Address = v.Host.Build()
|
||||||
}
|
}
|
||||||
config.Port = uint32(this.PortValue)
|
config.Port = uint32(v.PortValue)
|
||||||
config.NetworkList = this.NetworkList.Build()
|
config.NetworkList = v.NetworkList.Build()
|
||||||
config.Timeout = this.TimeoutValue
|
config.Timeout = v.TimeoutValue
|
||||||
config.FollowRedirect = this.Redirect
|
config.FollowRedirect = v.Redirect
|
||||||
return loader.NewTypedSettings(config), nil
|
return loader.NewTypedSettings(config), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,13 +12,13 @@ type FreedomConfig struct {
|
||||||
Timeout uint32 `json:"timeout"`
|
Timeout uint32 `json:"timeout"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *FreedomConfig) Build() (*loader.TypedSettings, error) {
|
func (v *FreedomConfig) Build() (*loader.TypedSettings, error) {
|
||||||
config := new(freedom.Config)
|
config := new(freedom.Config)
|
||||||
config.DomainStrategy = freedom.Config_AS_IS
|
config.DomainStrategy = freedom.Config_AS_IS
|
||||||
domainStrategy := strings.ToLower(this.DomainStrategy)
|
domainStrategy := strings.ToLower(v.DomainStrategy)
|
||||||
if domainStrategy == "useip" || domainStrategy == "use_ip" {
|
if domainStrategy == "useip" || domainStrategy == "use_ip" {
|
||||||
config.DomainStrategy = freedom.Config_USE_IP
|
config.DomainStrategy = freedom.Config_USE_IP
|
||||||
}
|
}
|
||||||
config.Timeout = this.Timeout
|
config.Timeout = v.Timeout
|
||||||
return loader.NewTypedSettings(config), nil
|
return loader.NewTypedSettings(config), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@ type HttpServerConfig struct {
|
||||||
Timeout uint32 `json:"timeout"`
|
Timeout uint32 `json:"timeout"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *HttpServerConfig) Build() (*loader.TypedSettings, error) {
|
func (v *HttpServerConfig) Build() (*loader.TypedSettings, error) {
|
||||||
config := &http.ServerConfig{
|
config := &http.ServerConfig{
|
||||||
Timeout: this.Timeout,
|
Timeout: v.Timeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
return loader.NewTypedSettings(config), nil
|
return loader.NewTypedSettings(config), nil
|
||||||
|
|
|
@ -16,17 +16,17 @@ type ConfigCreator func() interface{}
|
||||||
|
|
||||||
type ConfigCreatorCache map[string]ConfigCreator
|
type ConfigCreatorCache map[string]ConfigCreator
|
||||||
|
|
||||||
func (this ConfigCreatorCache) RegisterCreator(id string, creator ConfigCreator) error {
|
func (v ConfigCreatorCache) RegisterCreator(id string, creator ConfigCreator) error {
|
||||||
if _, found := this[id]; found {
|
if _, found := v[id]; found {
|
||||||
return common.ErrDuplicatedName
|
return common.ErrDuplicatedName
|
||||||
}
|
}
|
||||||
|
|
||||||
this[id] = creator
|
v[id] = creator
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this ConfigCreatorCache) CreateConfig(id string) (interface{}, error) {
|
func (v ConfigCreatorCache) CreateConfig(id string) (interface{}, error) {
|
||||||
creator, found := this[id]
|
creator, found := v[id]
|
||||||
if !found {
|
if !found {
|
||||||
return nil, ErrUnknownConfigID
|
return nil, ErrUnknownConfigID
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,8 @@ func NewJSONConfigLoader(cache ConfigCreatorCache, idKey string, configKey strin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *JSONConfigLoader) LoadWithID(raw []byte, id string) (interface{}, error) {
|
func (v *JSONConfigLoader) LoadWithID(raw []byte, id string) (interface{}, error) {
|
||||||
creator, found := this.cache[id]
|
creator, found := v.cache[id]
|
||||||
if !found {
|
if !found {
|
||||||
return nil, ErrUnknownConfigID
|
return nil, ErrUnknownConfigID
|
||||||
}
|
}
|
||||||
|
@ -60,14 +60,14 @@ func (this *JSONConfigLoader) LoadWithID(raw []byte, id string) (interface{}, er
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *JSONConfigLoader) Load(raw []byte) (interface{}, string, error) {
|
func (v *JSONConfigLoader) Load(raw []byte) (interface{}, string, error) {
|
||||||
var obj map[string]json.RawMessage
|
var obj map[string]json.RawMessage
|
||||||
if err := json.Unmarshal(raw, &obj); err != nil {
|
if err := json.Unmarshal(raw, &obj); err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
rawID, found := obj[this.idKey]
|
rawID, found := obj[v.idKey]
|
||||||
if !found {
|
if !found {
|
||||||
log.Error(this.idKey, " not found in JSON content.")
|
log.Error(v.idKey, " not found in JSON content.")
|
||||||
return nil, "", common.ErrObjectNotFound
|
return nil, "", common.ErrObjectNotFound
|
||||||
}
|
}
|
||||||
var id string
|
var id string
|
||||||
|
@ -75,15 +75,15 @@ func (this *JSONConfigLoader) Load(raw []byte) (interface{}, string, error) {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
rawConfig := json.RawMessage(raw)
|
rawConfig := json.RawMessage(raw)
|
||||||
if len(this.configKey) > 0 {
|
if len(v.configKey) > 0 {
|
||||||
configValue, found := obj[this.configKey]
|
configValue, found := obj[v.configKey]
|
||||||
if !found {
|
if !found {
|
||||||
log.Error(this.configKey, " not found in JSON content.")
|
log.Error(v.configKey, " not found in JSON content.")
|
||||||
return nil, "", common.ErrObjectNotFound
|
return nil, "", common.ErrObjectNotFound
|
||||||
}
|
}
|
||||||
rawConfig = configValue
|
rawConfig = configValue
|
||||||
}
|
}
|
||||||
config, err := this.LoadWithID([]byte(rawConfig), id)
|
config, err := v.LoadWithID([]byte(rawConfig), id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, id, err
|
return nil, id, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ type LogConfig struct {
|
||||||
LogLevel string `json:"loglevel"`
|
LogLevel string `json:"loglevel"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *LogConfig) Build() *log.Config {
|
func (v *LogConfig) Build() *log.Config {
|
||||||
if this == nil {
|
if v == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
config := &log.Config{
|
config := &log.Config{
|
||||||
|
@ -21,16 +21,16 @@ func (this *LogConfig) Build() *log.Config {
|
||||||
AccessLogType: log.LogType_Console,
|
AccessLogType: log.LogType_Console,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(this.AccessLog) > 0 {
|
if len(v.AccessLog) > 0 {
|
||||||
config.AccessLogPath = this.AccessLog
|
config.AccessLogPath = v.AccessLog
|
||||||
config.AccessLogType = log.LogType_File
|
config.AccessLogType = log.LogType_File
|
||||||
}
|
}
|
||||||
if len(this.ErrorLog) > 0 {
|
if len(v.ErrorLog) > 0 {
|
||||||
config.ErrorLogPath = this.ErrorLog
|
config.ErrorLogPath = v.ErrorLog
|
||||||
config.ErrorLogType = log.LogType_File
|
config.ErrorLogType = log.LogType_File
|
||||||
}
|
}
|
||||||
|
|
||||||
level := strings.ToLower(this.LogLevel)
|
level := strings.ToLower(v.LogLevel)
|
||||||
switch level {
|
switch level {
|
||||||
case "debug":
|
case "debug":
|
||||||
config.ErrorLogLevel = log.LogLevel_Debug
|
config.ErrorLogLevel = log.LogLevel_Debug
|
||||||
|
|
|
@ -23,13 +23,13 @@ type RouterConfig struct {
|
||||||
Settings *RouterRulesConfig `json:"settings"`
|
Settings *RouterRulesConfig `json:"settings"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *RouterConfig) Build() (*router.Config, error) {
|
func (v *RouterConfig) Build() (*router.Config, error) {
|
||||||
if this.Settings == nil {
|
if v.Settings == nil {
|
||||||
return nil, errors.New("Router settings is not specified.")
|
return nil, errors.New("Router settings is not specified.")
|
||||||
}
|
}
|
||||||
config := new(router.Config)
|
config := new(router.Config)
|
||||||
|
|
||||||
settings := this.Settings
|
settings := v.Settings
|
||||||
config.DomainStrategy = router.Config_AsIs
|
config.DomainStrategy = router.Config_AsIs
|
||||||
config.Rule = make([]*router.RoutingRule, len(settings.RuleList))
|
config.Rule = make([]*router.RoutingRule, len(settings.RuleList))
|
||||||
domainStrategy := strings.ToLower(settings.DomainStrategy)
|
domainStrategy := strings.ToLower(settings.DomainStrategy)
|
||||||
|
|
|
@ -18,25 +18,25 @@ type ShadowsocksServerConfig struct {
|
||||||
OTA *bool `json:"ota"`
|
OTA *bool `json:"ota"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ShadowsocksServerConfig) Build() (*loader.TypedSettings, error) {
|
func (v *ShadowsocksServerConfig) Build() (*loader.TypedSettings, error) {
|
||||||
config := new(shadowsocks.ServerConfig)
|
config := new(shadowsocks.ServerConfig)
|
||||||
config.UdpEnabled = this.UDP
|
config.UdpEnabled = v.UDP
|
||||||
|
|
||||||
if len(this.Password) == 0 {
|
if len(v.Password) == 0 {
|
||||||
return nil, errors.New("Shadowsocks password is not specified.")
|
return nil, errors.New("Shadowsocks password is not specified.")
|
||||||
}
|
}
|
||||||
account := &shadowsocks.Account{
|
account := &shadowsocks.Account{
|
||||||
Password: this.Password,
|
Password: v.Password,
|
||||||
Ota: shadowsocks.Account_Auto,
|
Ota: shadowsocks.Account_Auto,
|
||||||
}
|
}
|
||||||
if this.OTA != nil {
|
if v.OTA != nil {
|
||||||
if *this.OTA {
|
if *v.OTA {
|
||||||
account.Ota = shadowsocks.Account_Enabled
|
account.Ota = shadowsocks.Account_Enabled
|
||||||
} else {
|
} else {
|
||||||
account.Ota = shadowsocks.Account_Disabled
|
account.Ota = shadowsocks.Account_Disabled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cipher := strings.ToLower(this.Cipher)
|
cipher := strings.ToLower(v.Cipher)
|
||||||
switch cipher {
|
switch cipher {
|
||||||
case "aes-256-cfb":
|
case "aes-256-cfb":
|
||||||
account.CipherType = shadowsocks.CipherType_AES_256_CFB
|
account.CipherType = shadowsocks.CipherType_AES_256_CFB
|
||||||
|
@ -51,8 +51,8 @@ func (this *ShadowsocksServerConfig) Build() (*loader.TypedSettings, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
config.User = &protocol.User{
|
config.User = &protocol.User{
|
||||||
Email: this.Email,
|
Email: v.Email,
|
||||||
Level: uint32(this.Level),
|
Level: uint32(v.Level),
|
||||||
Account: loader.NewTypedSettings(account),
|
Account: loader.NewTypedSettings(account),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,15 +72,15 @@ type ShadowsocksClientConfig struct {
|
||||||
Servers []*ShadowsocksServerTarget `json:"servers"`
|
Servers []*ShadowsocksServerTarget `json:"servers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ShadowsocksClientConfig) Build() (*loader.TypedSettings, error) {
|
func (v *ShadowsocksClientConfig) Build() (*loader.TypedSettings, error) {
|
||||||
config := new(shadowsocks.ClientConfig)
|
config := new(shadowsocks.ClientConfig)
|
||||||
|
|
||||||
if len(this.Servers) == 0 {
|
if len(v.Servers) == 0 {
|
||||||
return nil, errors.New("0 Shadowsocks server configured.")
|
return nil, errors.New("0 Shadowsocks server configured.")
|
||||||
}
|
}
|
||||||
|
|
||||||
serverSpecs := make([]*protocol.ServerEndpoint, len(this.Servers))
|
serverSpecs := make([]*protocol.ServerEndpoint, len(v.Servers))
|
||||||
for idx, server := range this.Servers {
|
for idx, server := range v.Servers {
|
||||||
if server.Address == nil {
|
if server.Address == nil {
|
||||||
return nil, errors.New("Shadowsocks server address is not set.")
|
return nil, errors.New("Shadowsocks server address is not set.")
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,10 @@ type SocksAccount struct {
|
||||||
Password string `json:"pass"`
|
Password string `json:"pass"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *SocksAccount) Build() *socks.Account {
|
func (v *SocksAccount) Build() *socks.Account {
|
||||||
return &socks.Account{
|
return &socks.Account{
|
||||||
Username: this.Username,
|
Username: v.Username,
|
||||||
Password: this.Password,
|
Password: v.Password,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,29 +34,29 @@ type SocksServerConfig struct {
|
||||||
Timeout uint32 `json:"timeout"`
|
Timeout uint32 `json:"timeout"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *SocksServerConfig) Build() (*loader.TypedSettings, error) {
|
func (v *SocksServerConfig) Build() (*loader.TypedSettings, error) {
|
||||||
config := new(socks.ServerConfig)
|
config := new(socks.ServerConfig)
|
||||||
if this.AuthMethod == AuthMethodNoAuth {
|
if v.AuthMethod == AuthMethodNoAuth {
|
||||||
config.AuthType = socks.AuthType_NO_AUTH
|
config.AuthType = socks.AuthType_NO_AUTH
|
||||||
} else if this.AuthMethod == AuthMethodUserPass {
|
} else if v.AuthMethod == AuthMethodUserPass {
|
||||||
config.AuthType = socks.AuthType_PASSWORD
|
config.AuthType = socks.AuthType_PASSWORD
|
||||||
} else {
|
} else {
|
||||||
return nil, errors.New("Unknown socks auth method: " + this.AuthMethod)
|
return nil, errors.New("Unknown socks auth method: " + v.AuthMethod)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(this.Accounts) > 0 {
|
if len(v.Accounts) > 0 {
|
||||||
config.Accounts = make(map[string]string, len(this.Accounts))
|
config.Accounts = make(map[string]string, len(v.Accounts))
|
||||||
for _, account := range this.Accounts {
|
for _, account := range v.Accounts {
|
||||||
config.Accounts[account.Username] = account.Password
|
config.Accounts[account.Username] = account.Password
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config.UdpEnabled = this.UDP
|
config.UdpEnabled = v.UDP
|
||||||
if this.Host != nil {
|
if v.Host != nil {
|
||||||
config.Address = this.Host.Build()
|
config.Address = v.Host.Build()
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Timeout = this.Timeout
|
config.Timeout = v.Timeout
|
||||||
return loader.NewTypedSettings(config), nil
|
return loader.NewTypedSettings(config), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,10 +69,10 @@ type SocksClientConfig struct {
|
||||||
Servers []*SocksRemoteConfig `json:"servers"`
|
Servers []*SocksRemoteConfig `json:"servers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *SocksClientConfig) Build() (*loader.TypedSettings, error) {
|
func (v *SocksClientConfig) Build() (*loader.TypedSettings, error) {
|
||||||
config := new(socks.ClientConfig)
|
config := new(socks.ClientConfig)
|
||||||
config.Server = make([]*protocol.ServerEndpoint, len(this.Servers))
|
config.Server = make([]*protocol.ServerEndpoint, len(v.Servers))
|
||||||
for idx, serverConfig := range this.Servers {
|
for idx, serverConfig := range v.Servers {
|
||||||
server := &protocol.ServerEndpoint{
|
server := &protocol.ServerEndpoint{
|
||||||
Address: serverConfig.Address.Build(),
|
Address: serverConfig.Address.Build(),
|
||||||
Port: uint32(serverConfig.Port),
|
Port: uint32(serverConfig.Port),
|
||||||
|
|
|
@ -14,11 +14,11 @@ type TransportConfig struct {
|
||||||
WSConfig *WebSocketConfig `json:"wsSettings"`
|
WSConfig *WebSocketConfig `json:"wsSettings"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TransportConfig) Build() (*transport.Config, error) {
|
func (v *TransportConfig) Build() (*transport.Config, error) {
|
||||||
config := new(transport.Config)
|
config := new(transport.Config)
|
||||||
|
|
||||||
if this.TCPConfig != nil {
|
if v.TCPConfig != nil {
|
||||||
ts, err := this.TCPConfig.Build()
|
ts, err := v.TCPConfig.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("Failed to build TCP config: " + err.Error())
|
return nil, errors.New("Failed to build TCP config: " + err.Error())
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ func (this *TransportConfig) Build() (*transport.Config, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.KCPConfig != nil {
|
if v.KCPConfig != nil {
|
||||||
ts, err := this.KCPConfig.Build()
|
ts, err := v.KCPConfig.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("Failed to build KCP config: " + err.Error())
|
return nil, errors.New("Failed to build KCP config: " + err.Error())
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,8 @@ func (this *TransportConfig) Build() (*transport.Config, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if this.WSConfig != nil {
|
if v.WSConfig != nil {
|
||||||
ts, err := this.WSConfig.Build()
|
ts, err := v.WSConfig.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("Failed to build WebSocket config: " + err.Error())
|
return nil, errors.New("Failed to build WebSocket config: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ type HTTPAuthenticatorRequest struct {
|
||||||
Headers map[string]*StringList `json:"headers"`
|
Headers map[string]*StringList `json:"headers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *HTTPAuthenticatorRequest) Build() (*http.RequestConfig, error) {
|
func (v *HTTPAuthenticatorRequest) Build() (*http.RequestConfig, error) {
|
||||||
config := &http.RequestConfig{
|
config := &http.RequestConfig{
|
||||||
Uri: []string{"/"},
|
Uri: []string{"/"},
|
||||||
Header: []*http.Header{
|
Header: []*http.Header{
|
||||||
|
@ -71,21 +71,21 @@ func (this *HTTPAuthenticatorRequest) Build() (*http.RequestConfig, error) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(this.Version) > 0 {
|
if len(v.Version) > 0 {
|
||||||
config.Version = &http.Version{Value: this.Version}
|
config.Version = &http.Version{Value: v.Version}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(this.Method) > 0 {
|
if len(v.Method) > 0 {
|
||||||
config.Method = &http.Method{Value: this.Method}
|
config.Method = &http.Method{Value: v.Method}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(this.Path) > 0 {
|
if len(v.Path) > 0 {
|
||||||
config.Uri = append([]string(nil), (this.Path)...)
|
config.Uri = append([]string(nil), (v.Path)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(this.Headers) > 0 {
|
if len(v.Headers) > 0 {
|
||||||
config.Header = make([]*http.Header, 0, len(this.Headers))
|
config.Header = make([]*http.Header, 0, len(v.Headers))
|
||||||
for key, value := range this.Headers {
|
for key, value := range v.Headers {
|
||||||
if value == nil {
|
if value == nil {
|
||||||
return nil, errors.New("Empty HTTP header value: " + key)
|
return nil, errors.New("Empty HTTP header value: " + key)
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ type HTTPAuthenticatorResponse struct {
|
||||||
Headers map[string]*StringList `json:"headers"`
|
Headers map[string]*StringList `json:"headers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *HTTPAuthenticatorResponse) Build() (*http.ResponseConfig, error) {
|
func (v *HTTPAuthenticatorResponse) Build() (*http.ResponseConfig, error) {
|
||||||
config := &http.ResponseConfig{
|
config := &http.ResponseConfig{
|
||||||
Header: []*http.Header{
|
Header: []*http.Header{
|
||||||
{
|
{
|
||||||
|
@ -128,26 +128,26 @@ func (this *HTTPAuthenticatorResponse) Build() (*http.ResponseConfig, error) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(this.Version) > 0 {
|
if len(v.Version) > 0 {
|
||||||
config.Version = &http.Version{Value: this.Version}
|
config.Version = &http.Version{Value: v.Version}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(this.Status) > 0 || len(this.Reason) > 0 {
|
if len(v.Status) > 0 || len(v.Reason) > 0 {
|
||||||
config.Status = &http.Status{
|
config.Status = &http.Status{
|
||||||
Code: "200",
|
Code: "200",
|
||||||
Reason: "OK",
|
Reason: "OK",
|
||||||
}
|
}
|
||||||
if len(this.Status) > 0 {
|
if len(v.Status) > 0 {
|
||||||
config.Status.Code = this.Status
|
config.Status.Code = v.Status
|
||||||
}
|
}
|
||||||
if len(this.Reason) > 0 {
|
if len(v.Reason) > 0 {
|
||||||
config.Status.Reason = this.Reason
|
config.Status.Reason = v.Reason
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(this.Headers) > 0 {
|
if len(v.Headers) > 0 {
|
||||||
config.Header = make([]*http.Header, 0, len(this.Headers))
|
config.Header = make([]*http.Header, 0, len(v.Headers))
|
||||||
for key, value := range this.Headers {
|
for key, value := range v.Headers {
|
||||||
if value == nil {
|
if value == nil {
|
||||||
return nil, errors.New("Empty HTTP header value: " + key)
|
return nil, errors.New("Empty HTTP header value: " + key)
|
||||||
}
|
}
|
||||||
|
@ -166,15 +166,15 @@ type HTTPAuthenticator struct {
|
||||||
Response HTTPAuthenticatorResponse `json:"response"`
|
Response HTTPAuthenticatorResponse `json:"response"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *HTTPAuthenticator) Build() (*loader.TypedSettings, error) {
|
func (v *HTTPAuthenticator) Build() (*loader.TypedSettings, error) {
|
||||||
config := new(http.Config)
|
config := new(http.Config)
|
||||||
requestConfig, err := this.Request.Build()
|
requestConfig, err := v.Request.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
config.Request = requestConfig
|
config.Request = requestConfig
|
||||||
|
|
||||||
responseConfig, err := this.Response.Build()
|
responseConfig, err := v.Response.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,50 +40,50 @@ type KCPConfig struct {
|
||||||
HeaderConfig json.RawMessage `json:"header"`
|
HeaderConfig json.RawMessage `json:"header"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *KCPConfig) Build() (*loader.TypedSettings, error) {
|
func (v *KCPConfig) Build() (*loader.TypedSettings, error) {
|
||||||
config := new(kcp.Config)
|
config := new(kcp.Config)
|
||||||
|
|
||||||
if this.Mtu != nil {
|
if v.Mtu != nil {
|
||||||
mtu := *this.Mtu
|
mtu := *v.Mtu
|
||||||
if mtu < 576 || mtu > 1460 {
|
if mtu < 576 || mtu > 1460 {
|
||||||
return nil, fmt.Errorf("KCP|Config: Invalid MTU size: %d", mtu)
|
return nil, fmt.Errorf("KCP|Config: Invalid MTU size: %d", mtu)
|
||||||
}
|
}
|
||||||
config.Mtu = &kcp.MTU{Value: mtu}
|
config.Mtu = &kcp.MTU{Value: mtu}
|
||||||
}
|
}
|
||||||
if this.Tti != nil {
|
if v.Tti != nil {
|
||||||
tti := *this.Tti
|
tti := *v.Tti
|
||||||
if tti < 10 || tti > 100 {
|
if tti < 10 || tti > 100 {
|
||||||
return nil, fmt.Errorf("KCP|Config: Invalid TTI: %d", tti)
|
return nil, fmt.Errorf("KCP|Config: Invalid TTI: %d", tti)
|
||||||
}
|
}
|
||||||
config.Tti = &kcp.TTI{Value: tti}
|
config.Tti = &kcp.TTI{Value: tti}
|
||||||
}
|
}
|
||||||
if this.UpCap != nil {
|
if v.UpCap != nil {
|
||||||
config.UplinkCapacity = &kcp.UplinkCapacity{Value: *this.UpCap}
|
config.UplinkCapacity = &kcp.UplinkCapacity{Value: *v.UpCap}
|
||||||
}
|
}
|
||||||
if this.DownCap != nil {
|
if v.DownCap != nil {
|
||||||
config.DownlinkCapacity = &kcp.DownlinkCapacity{Value: *this.DownCap}
|
config.DownlinkCapacity = &kcp.DownlinkCapacity{Value: *v.DownCap}
|
||||||
}
|
}
|
||||||
if this.Congestion != nil {
|
if v.Congestion != nil {
|
||||||
config.Congestion = *this.Congestion
|
config.Congestion = *v.Congestion
|
||||||
}
|
}
|
||||||
if this.ReadBufferSize != nil {
|
if v.ReadBufferSize != nil {
|
||||||
size := *this.ReadBufferSize
|
size := *v.ReadBufferSize
|
||||||
if size > 0 {
|
if size > 0 {
|
||||||
config.ReadBuffer = &kcp.ReadBuffer{Size: size * 1024 * 1024}
|
config.ReadBuffer = &kcp.ReadBuffer{Size: size * 1024 * 1024}
|
||||||
} else {
|
} else {
|
||||||
config.ReadBuffer = &kcp.ReadBuffer{Size: 512 * 1024}
|
config.ReadBuffer = &kcp.ReadBuffer{Size: 512 * 1024}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if this.WriteBufferSize != nil {
|
if v.WriteBufferSize != nil {
|
||||||
size := *this.WriteBufferSize
|
size := *v.WriteBufferSize
|
||||||
if size > 0 {
|
if size > 0 {
|
||||||
config.WriteBuffer = &kcp.WriteBuffer{Size: size * 1024 * 1024}
|
config.WriteBuffer = &kcp.WriteBuffer{Size: size * 1024 * 1024}
|
||||||
} else {
|
} else {
|
||||||
config.WriteBuffer = &kcp.WriteBuffer{Size: 512 * 1024}
|
config.WriteBuffer = &kcp.WriteBuffer{Size: 512 * 1024}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(this.HeaderConfig) > 0 {
|
if len(v.HeaderConfig) > 0 {
|
||||||
headerConfig, _, err := kcpHeaderLoader.Load(this.HeaderConfig)
|
headerConfig, _, err := kcpHeaderLoader.Load(v.HeaderConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("KCP|Config: Failed to parse header config: " + err.Error())
|
return nil, errors.New("KCP|Config: Failed to parse header config: " + err.Error())
|
||||||
}
|
}
|
||||||
|
@ -102,15 +102,15 @@ type TCPConfig struct {
|
||||||
HeaderConfig json.RawMessage `json:"header"`
|
HeaderConfig json.RawMessage `json:"header"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TCPConfig) Build() (*loader.TypedSettings, error) {
|
func (v *TCPConfig) Build() (*loader.TypedSettings, error) {
|
||||||
config := new(tcp.Config)
|
config := new(tcp.Config)
|
||||||
if this.ConnectionReuse != nil {
|
if v.ConnectionReuse != nil {
|
||||||
config.ConnectionReuse = &tcp.ConnectionReuse{
|
config.ConnectionReuse = &tcp.ConnectionReuse{
|
||||||
Enable: *this.ConnectionReuse,
|
Enable: *v.ConnectionReuse,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(this.HeaderConfig) > 0 {
|
if len(v.HeaderConfig) > 0 {
|
||||||
headerConfig, _, err := tcpHeaderLoader.Load(this.HeaderConfig)
|
headerConfig, _, err := tcpHeaderLoader.Load(v.HeaderConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("TCP|Config: Failed to parse header config: " + err.Error())
|
return nil, errors.New("TCP|Config: Failed to parse header config: " + err.Error())
|
||||||
}
|
}
|
||||||
|
@ -129,13 +129,13 @@ type WebSocketConfig struct {
|
||||||
Path string `json:"Path"`
|
Path string `json:"Path"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *WebSocketConfig) Build() (*loader.TypedSettings, error) {
|
func (v *WebSocketConfig) Build() (*loader.TypedSettings, error) {
|
||||||
config := &ws.Config{
|
config := &ws.Config{
|
||||||
Path: this.Path,
|
Path: v.Path,
|
||||||
}
|
}
|
||||||
if this.ConnectionReuse != nil {
|
if v.ConnectionReuse != nil {
|
||||||
config.ConnectionReuse = &ws.ConnectionReuse{
|
config.ConnectionReuse = &ws.ConnectionReuse{
|
||||||
Enable: *this.ConnectionReuse,
|
Enable: *v.ConnectionReuse,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return loader.NewTypedSettings(config), nil
|
return loader.NewTypedSettings(config), nil
|
||||||
|
@ -150,10 +150,10 @@ type TLSConfig struct {
|
||||||
Certs []*TLSCertConfig `json:"certificates"`
|
Certs []*TLSCertConfig `json:"certificates"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TLSConfig) Build() (*loader.TypedSettings, error) {
|
func (v *TLSConfig) Build() (*loader.TypedSettings, error) {
|
||||||
config := new(tls.Config)
|
config := new(tls.Config)
|
||||||
config.Certificate = make([]*tls.Certificate, len(this.Certs))
|
config.Certificate = make([]*tls.Certificate, len(v.Certs))
|
||||||
for idx, certConf := range this.Certs {
|
for idx, certConf := range v.Certs {
|
||||||
cert, err := ioutil.ReadFile(certConf.CertFile)
|
cert, err := ioutil.ReadFile(certConf.CertFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("TLS: Failed to load certificate file: " + err.Error())
|
return nil, errors.New("TLS: Failed to load certificate file: " + err.Error())
|
||||||
|
@ -167,7 +167,7 @@ func (this *TLSConfig) Build() (*loader.TypedSettings, error) {
|
||||||
Certificate: cert,
|
Certificate: cert,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config.AllowInsecure = this.Insecure
|
config.AllowInsecure = v.Insecure
|
||||||
return loader.NewTypedSettings(config), nil
|
return loader.NewTypedSettings(config), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,15 +180,15 @@ type StreamConfig struct {
|
||||||
WSSettings *WebSocketConfig `json:"wsSettings"`
|
WSSettings *WebSocketConfig `json:"wsSettings"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *StreamConfig) Build() (*internet.StreamConfig, error) {
|
func (v *StreamConfig) Build() (*internet.StreamConfig, error) {
|
||||||
config := &internet.StreamConfig{
|
config := &internet.StreamConfig{
|
||||||
Network: v2net.Network_RawTCP,
|
Network: v2net.Network_RawTCP,
|
||||||
}
|
}
|
||||||
if this.Network != nil {
|
if v.Network != nil {
|
||||||
config.Network = (*this.Network).Build()
|
config.Network = (*v.Network).Build()
|
||||||
}
|
}
|
||||||
if strings.ToLower(this.Security) == "tls" {
|
if strings.ToLower(v.Security) == "tls" {
|
||||||
tlsSettings := this.TLSSettings
|
tlsSettings := v.TLSSettings
|
||||||
if tlsSettings == nil {
|
if tlsSettings == nil {
|
||||||
tlsSettings = &TLSConfig{}
|
tlsSettings = &TLSConfig{}
|
||||||
}
|
}
|
||||||
|
@ -198,8 +198,8 @@ func (this *StreamConfig) Build() (*internet.StreamConfig, error) {
|
||||||
}
|
}
|
||||||
config.SecuritySettings = append(config.SecuritySettings, ts)
|
config.SecuritySettings = append(config.SecuritySettings, ts)
|
||||||
}
|
}
|
||||||
if this.TCPSettings != nil {
|
if v.TCPSettings != nil {
|
||||||
ts, err := this.TCPSettings.Build()
|
ts, err := v.TCPSettings.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("Failed to build TCP config: " + err.Error())
|
return nil, errors.New("Failed to build TCP config: " + err.Error())
|
||||||
}
|
}
|
||||||
|
@ -208,8 +208,8 @@ func (this *StreamConfig) Build() (*internet.StreamConfig, error) {
|
||||||
Settings: ts,
|
Settings: ts,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if this.KCPSettings != nil {
|
if v.KCPSettings != nil {
|
||||||
ts, err := this.KCPSettings.Build()
|
ts, err := v.KCPSettings.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("Failed to build KCP config: " + err.Error())
|
return nil, errors.New("Failed to build KCP config: " + err.Error())
|
||||||
}
|
}
|
||||||
|
@ -218,8 +218,8 @@ func (this *StreamConfig) Build() (*internet.StreamConfig, error) {
|
||||||
Settings: ts,
|
Settings: ts,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if this.WSSettings != nil {
|
if v.WSSettings != nil {
|
||||||
ts, err := this.WSSettings.Build()
|
ts, err := v.WSSettings.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("Failed to build WebSocket config: " + err.Error())
|
return nil, errors.New("Failed to build WebSocket config: " + err.Error())
|
||||||
}
|
}
|
||||||
|
@ -235,11 +235,11 @@ type ProxyConfig struct {
|
||||||
Tag string `json:"tag"`
|
Tag string `json:"tag"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ProxyConfig) Build() (*internet.ProxyConfig, error) {
|
func (v *ProxyConfig) Build() (*internet.ProxyConfig, error) {
|
||||||
if len(this.Tag) == 0 {
|
if len(v.Tag) == 0 {
|
||||||
return nil, errors.New("Proxy tag is not set.")
|
return nil, errors.New("Proxy tag is not set.")
|
||||||
}
|
}
|
||||||
return &internet.ProxyConfig{
|
return &internet.ProxyConfig{
|
||||||
Tag: this.Tag,
|
Tag: v.Tag,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue