Przeglądaj źródła

move common/log to app/log

Darien Raymond 8 lat temu
rodzic
commit
f046f334cd
59 zmienionych plików z 290 dodań i 154 usunięć
  1. 2 0
      app/dispatcher/dispatcher.go
  2. 7 1
      app/dispatcher/impl/default.go
  3. 1 1
      app/dns/config.go
  4. 2 0
      app/dns/dns.go
  5. 1 1
      app/dns/server/nameserver.go
  6. 7 1
      app/dns/server/server.go
  7. 1 1
      app/log/access.go
  8. 0 0
      app/log/config.go
  9. 29 29
      app/log/config.pb.go
  10. 3 2
      app/log/config.proto
  11. 0 0
      app/log/internal/log_entry.go
  12. 1 1
      app/log/internal/log_entry_test.go
  13. 0 0
      app/log/internal/log_writer.go
  14. 0 0
      app/log/internal/log_writer_test.go
  15. 54 2
      app/log/log.go
  16. 1 1
      app/proxyman/inbound/always.go
  17. 1 1
      app/proxyman/inbound/dynamic.go
  18. 1 1
      app/proxyman/outbound/handler.go
  19. 4 0
      app/proxyman/outbound/outbound.go
  20. 2 0
      app/proxyman/proxyman.go
  21. 7 1
      app/router/router.go
  22. 20 4
      app/space.go
  23. 1 1
      common/net/address.go
  24. 22 32
      config.pb.go
  25. 1 2
      config.proto
  26. 1 1
      proxy/dokodemo/dokodemo.go
  27. 1 1
      proxy/freedom/freedom.go
  28. 1 1
      proxy/http/server.go
  29. 1 1
      proxy/shadowsocks/client.go
  30. 1 1
      proxy/shadowsocks/server.go
  31. 1 1
      proxy/socks/client.go
  32. 1 1
      proxy/socks/server.go
  33. 10 1
      proxy/vmess/account.go
  34. 46 18
      proxy/vmess/account.pb.go
  35. 6 0
      proxy/vmess/account.proto
  36. 1 1
      proxy/vmess/encoding/client.go
  37. 1 1
      proxy/vmess/encoding/server.go
  38. 1 1
      proxy/vmess/inbound/inbound.go
  39. 1 1
      proxy/vmess/outbound/outbound.go
  40. 1 1
      testing/scenarios/server_env.go
  41. 1 1
      tools/conf/common.go
  42. 1 1
      tools/conf/loader.go
  43. 1 1
      tools/conf/log.go
  44. 1 1
      tools/conf/router.go
  45. 1 1
      tools/conf/v2ray.go
  46. 1 1
      transport/internet/kcp/connection.go
  47. 1 1
      transport/internet/kcp/dialer.go
  48. 1 1
      transport/internet/kcp/listener.go
  49. 1 1
      transport/internet/tcp/dialer.go
  50. 1 1
      transport/internet/tcp/hub.go
  51. 1 1
      transport/internet/tcp/sockopt_linux.go
  52. 1 1
      transport/internet/tcp_hub.go
  53. 1 1
      transport/internet/tls/config.go
  54. 1 1
      transport/internet/udp/dispatcher.go
  55. 1 1
      transport/internet/udp/hub.go
  56. 1 1
      transport/internet/websocket/dialer.go
  57. 1 1
      transport/internet/websocket/hub.go
  58. 1 1
      transport/internet/websocket/wsconn.go
  59. 30 23
      v2ray.go

+ 2 - 0
app/dispatcher/dispatcher.go

@@ -10,6 +10,8 @@ import (
 // Interface dispatch a packet and possibly further network payload to its destination.
 type Interface interface {
 	DispatchToOutbound(ctx context.Context) ray.InboundRay
+	Start() error
+	Close()
 }
 
 func FromSpace(space app.Space) Interface {

+ 7 - 1
app/dispatcher/impl/default.go

@@ -6,12 +6,12 @@ import (
 
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/dispatcher"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/app/proxyman"
 	"v2ray.com/core/app/router"
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
 	"v2ray.com/core/proxy"
 	"v2ray.com/core/transport/ray"
 )
@@ -38,6 +38,12 @@ func NewDefaultDispatcher(ctx context.Context, config *dispatcher.Config) (*Defa
 	return d, nil
 }
 
+func (DefaultDispatcher) Start() error {
+	return nil
+}
+
+func (DefaultDispatcher) Close() {}
+
 func (DefaultDispatcher) Interface() interface{} {
 	return (*dispatcher.Interface)(nil)
 }

+ 1 - 1
app/dns/config.go

@@ -3,7 +3,7 @@ package dns
 import (
 	"net"
 
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 )
 
 func (v *Config) GetInternalHosts() map[string]net.IP {

+ 2 - 0
app/dns/dns.go

@@ -9,6 +9,8 @@ import (
 // A Server is a DNS server for responding DNS queries.
 type Server interface {
 	Get(domain string) []net.IP
+	Start() error
+	Close()
 }
 
 func FromSpace(space app.Space) Server {

+ 1 - 1
app/dns/server/nameserver.go

@@ -10,7 +10,7 @@ import (
 	"v2ray.com/core/app/dispatcher"
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/dice"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet/udp"
 )

+ 7 - 1
app/dns/server/server.go

@@ -10,9 +10,9 @@ import (
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/dispatcher"
 	"v2ray.com/core/app/dns"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 )
 
@@ -73,6 +73,12 @@ func (CacheServer) Interface() interface{} {
 	return (*dns.Server)(nil)
 }
 
+func (CacheServer) Start() error {
+	return nil
+}
+
+func (CacheServer) Close() {}
+
 // Private: Visible for testing.
 func (v *CacheServer) GetCached(domain string) []net.IP {
 	v.RLock()

+ 1 - 1
common/log/access.go → app/log/access.go

@@ -1,7 +1,7 @@
 package log
 
 import (
-	"v2ray.com/core/common/log/internal"
+	"v2ray.com/core/app/log/internal"
 )
 
 // AccessStatus is the status of an access request from clients.

+ 0 - 0
common/log/config.go → app/log/config.go


+ 29 - 29
common/log/config.pb.go → app/log/config.pb.go

@@ -73,10 +73,10 @@ func (x LogLevel) String() string {
 func (LogLevel) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
 
 type Config struct {
-	ErrorLogType  LogType  `protobuf:"varint,1,opt,name=error_log_type,json=errorLogType,enum=v2ray.core.common.log.LogType" json:"error_log_type,omitempty"`
-	ErrorLogLevel LogLevel `protobuf:"varint,2,opt,name=error_log_level,json=errorLogLevel,enum=v2ray.core.common.log.LogLevel" json:"error_log_level,omitempty"`
+	ErrorLogType  LogType  `protobuf:"varint,1,opt,name=error_log_type,json=errorLogType,enum=v2ray.core.app.log.LogType" json:"error_log_type,omitempty"`
+	ErrorLogLevel LogLevel `protobuf:"varint,2,opt,name=error_log_level,json=errorLogLevel,enum=v2ray.core.app.log.LogLevel" json:"error_log_level,omitempty"`
 	ErrorLogPath  string   `protobuf:"bytes,3,opt,name=error_log_path,json=errorLogPath" json:"error_log_path,omitempty"`
-	AccessLogType LogType  `protobuf:"varint,4,opt,name=access_log_type,json=accessLogType,enum=v2ray.core.common.log.LogType" json:"access_log_type,omitempty"`
+	AccessLogType LogType  `protobuf:"varint,4,opt,name=access_log_type,json=accessLogType,enum=v2ray.core.app.log.LogType" json:"access_log_type,omitempty"`
 	AccessLogPath string   `protobuf:"bytes,5,opt,name=access_log_path,json=accessLogPath" json:"access_log_path,omitempty"`
 }
 
@@ -121,34 +121,34 @@ func (m *Config) GetAccessLogPath() string {
 }
 
 func init() {
-	proto.RegisterType((*Config)(nil), "v2ray.core.common.log.Config")
-	proto.RegisterEnum("v2ray.core.common.log.LogType", LogType_name, LogType_value)
-	proto.RegisterEnum("v2ray.core.common.log.LogLevel", LogLevel_name, LogLevel_value)
+	proto.RegisterType((*Config)(nil), "v2ray.core.app.log.Config")
+	proto.RegisterEnum("v2ray.core.app.log.LogType", LogType_name, LogType_value)
+	proto.RegisterEnum("v2ray.core.app.log.LogLevel", LogLevel_name, LogLevel_value)
 }
 
-func init() { proto.RegisterFile("v2ray.com/core/common/log/config.proto", fileDescriptor0) }
+func init() { proto.RegisterFile("v2ray.com/core/app/log/config.proto", fileDescriptor0) }
 
 var fileDescriptor0 = []byte{
-	// 322 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x91, 0x6d, 0x4b, 0xf3, 0x30,
-	0x14, 0x86, 0xd7, 0x76, 0xaf, 0xd9, 0x5b, 0x08, 0x3c, 0xb0, 0xe7, 0x8b, 0x0e, 0x91, 0x31, 0x06,
-	0xb6, 0x30, 0xf1, 0x0f, 0xec, 0x4d, 0x84, 0x21, 0x63, 0x08, 0x82, 0x5f, 0x46, 0x17, 0xcf, 0xb2,
-	0x42, 0x9a, 0x53, 0xd2, 0x3a, 0xd8, 0x8f, 0xf2, 0x3f, 0x4a, 0x32, 0x6b, 0x15, 0x26, 0xf8, 0x31,
-	0xe1, 0x3a, 0xd7, 0x7d, 0x1f, 0x0e, 0x19, 0x1c, 0xc6, 0x3a, 0x3c, 0xfa, 0x1c, 0xe3, 0x80, 0xa3,
-	0x86, 0x80, 0x63, 0x1c, 0xa3, 0x0a, 0x24, 0x8a, 0x80, 0xa3, 0xda, 0x45, 0xc2, 0x4f, 0x34, 0x66,
-	0xc8, 0xfe, 0xe5, 0x9c, 0x06, 0xff, 0xc4, 0xf8, 0x12, 0xc5, 0xd5, 0xbb, 0x4b, 0xaa, 0x53, 0xcb,
-	0xb1, 0x19, 0xe9, 0x80, 0xd6, 0xa8, 0x37, 0x12, 0xc5, 0x26, 0x3b, 0x26, 0xd0, 0x73, 0xfa, 0xce,
-	0xb0, 0x33, 0xbe, 0xf0, 0xcf, 0x8e, 0xfa, 0x4b, 0x14, 0x4f, 0xc7, 0x04, 0xd6, 0x2d, 0x3b, 0xf5,
-	0xf9, 0x62, 0xf7, 0xa4, 0x5b, 0x58, 0x24, 0x1c, 0x40, 0xf6, 0x5c, 0xab, 0xb9, 0xfc, 0x5d, 0xb3,
-	0x34, 0xd8, 0xba, 0x9d, 0x7b, 0xec, 0x93, 0x5d, 0x7f, 0xaf, 0x93, 0x84, 0xd9, 0xbe, 0xe7, 0xf5,
-	0x9d, 0x61, 0xa3, 0x88, 0x5b, 0x85, 0xd9, 0x9e, 0x2d, 0x48, 0x37, 0xe4, 0x1c, 0xd2, 0xb4, 0x68,
-	0x5d, 0xfe, 0x53, 0xeb, 0xf6, 0x69, 0x2c, 0xaf, 0x3d, 0xf8, 0xe1, 0xb1, 0x71, 0x15, 0x1b, 0x57,
-	0x70, 0x26, 0x6f, 0x74, 0x47, 0x6a, 0xf9, 0x48, 0x9d, 0x94, 0x1f, 0x51, 0x01, 0x2d, 0xb1, 0x26,
-	0xa9, 0x4d, 0x51, 0xa5, 0x28, 0x81, 0x3a, 0xe6, 0x7b, 0x11, 0x49, 0xa0, 0x2e, 0x6b, 0x90, 0xca,
-	0xfc, 0x00, 0x2a, 0xa3, 0xde, 0x68, 0x4e, 0xea, 0x5f, 0x8b, 0xb5, 0x48, 0x7d, 0x16, 0xa5, 0xe1,
-	0x56, 0xc2, 0x2b, 0x2d, 0x59, 0xc8, 0x2c, 0x44, 0x1d, 0xa3, 0x79, 0x0e, 0xb5, 0x8a, 0x94, 0xa0,
-	0xae, 0xd1, 0x3c, 0xa8, 0x1d, 0x52, 0xcf, 0x10, 0x33, 0xd8, 0xbe, 0x09, 0x5a, 0x9e, 0xdc, 0x90,
-	0xff, 0x1c, 0xe3, 0xf3, 0x9b, 0x4d, 0x9a, 0xa7, 0x3b, 0xae, 0xcc, 0xb9, 0x5f, 0x3c, 0x89, 0x62,
-	0x5b, 0xb5, 0xa7, 0xbf, 0xfd, 0x08, 0x00, 0x00, 0xff, 0xff, 0x11, 0x55, 0x7e, 0x04, 0x24, 0x02,
-	0x00, 0x00,
+	// 335 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x92, 0xcf, 0x4b, 0xc3, 0x30,
+	0x1c, 0xc5, 0xd7, 0x76, 0x3f, 0xb3, 0x5f, 0x21, 0x07, 0x19, 0xe8, 0x61, 0xa8, 0xc8, 0xd8, 0xa1,
+	0x85, 0x89, 0x67, 0xd9, 0xba, 0x09, 0xc2, 0x90, 0x31, 0x44, 0xc1, 0xcb, 0xc8, 0x6a, 0x96, 0x15,
+	0xb2, 0x7c, 0x43, 0x5a, 0x07, 0xfd, 0x7f, 0x3c, 0xf9, 0x57, 0x4a, 0x32, 0x6b, 0x15, 0x15, 0x8f,
+	0x29, 0xef, 0x7d, 0xde, 0x7b, 0x7c, 0x8b, 0xce, 0xf6, 0x23, 0x4d, 0x33, 0x3f, 0x82, 0x5d, 0x10,
+	0x81, 0x66, 0x01, 0x55, 0x2a, 0x10, 0xc0, 0x83, 0x08, 0xe4, 0x26, 0xe6, 0xbe, 0xd2, 0x90, 0x02,
+	0x21, 0xb9, 0x48, 0x33, 0x9f, 0x2a, 0xe5, 0x0b, 0xe0, 0xa7, 0xaf, 0x2e, 0xaa, 0x86, 0x56, 0x44,
+	0xc6, 0xa8, 0xc3, 0xb4, 0x06, 0xbd, 0x12, 0xc0, 0x57, 0x69, 0xa6, 0x58, 0xcf, 0xe9, 0x3b, 0x83,
+	0xce, 0xe8, 0xd8, 0xff, 0xe9, 0xf3, 0xe7, 0xc0, 0xef, 0x33, 0xc5, 0x96, 0x2d, 0x6b, 0xf9, 0x78,
+	0x91, 0x29, 0xea, 0x16, 0x08, 0xc1, 0xf6, 0x4c, 0xf4, 0x5c, 0xcb, 0x38, 0xf9, 0x83, 0x31, 0x37,
+	0x9a, 0x65, 0x3b, 0x87, 0xd8, 0x27, 0x39, 0xff, 0x5a, 0x44, 0xd1, 0x74, 0xdb, 0xf3, 0xfa, 0xce,
+	0xa0, 0x51, 0x64, 0x2d, 0x68, 0xba, 0x25, 0x21, 0xea, 0xd2, 0x28, 0x62, 0x49, 0x52, 0xf4, 0x2d,
+	0xff, 0xdf, 0xb7, 0x7d, 0xf0, 0xe4, 0x85, 0x2f, 0xbe, 0x41, 0x6c, 0x56, 0xc5, 0x66, 0x15, 0x3a,
+	0x13, 0x36, 0xbc, 0x42, 0xb5, 0xdc, 0x52, 0x47, 0xe5, 0x3b, 0x90, 0x0c, 0x97, 0x48, 0x13, 0xd5,
+	0x42, 0x90, 0x09, 0x08, 0x86, 0x1d, 0xf3, 0xf9, 0x26, 0x16, 0x0c, 0xbb, 0xa4, 0x81, 0x2a, 0xb3,
+	0x3d, 0x93, 0x29, 0xf6, 0x86, 0x33, 0x54, 0xff, 0x5c, 0xd5, 0x42, 0xf5, 0x69, 0x9c, 0xd0, 0xb5,
+	0x60, 0xcf, 0xb8, 0x64, 0x45, 0x66, 0x0d, 0x76, 0x0c, 0xe6, 0x91, 0x6a, 0x19, 0x4b, 0x8e, 0x5d,
+	0x83, 0xb9, 0x95, 0x1b, 0xc0, 0x9e, 0x51, 0x4c, 0xd9, 0xfa, 0x85, 0xe3, 0xf2, 0xe4, 0x1a, 0x1d,
+	0x45, 0xb0, 0xfb, 0x65, 0xd6, 0xa4, 0x79, 0xb8, 0xdd, 0xc2, 0xdc, 0xf7, 0xc9, 0x13, 0xc0, 0xdf,
+	0x5c, 0xf2, 0x30, 0x5a, 0xd2, 0xcc, 0x0f, 0x8d, 0x6c, 0xac, 0x94, 0x59, 0xbe, 0xae, 0xda, 0x1f,
+	0xe0, 0xf2, 0x3d, 0x00, 0x00, 0xff, 0xff, 0x89, 0x56, 0x54, 0xa7, 0x27, 0x02, 0x00, 0x00,
 }

+ 3 - 2
common/log/config.proto → app/log/config.proto

@@ -1,8 +1,9 @@
 syntax = "proto3";
 
-package v2ray.core.common.log;
+package v2ray.core.app.log;
+option csharp_namespace = "V2Ray.Core.App.Log";
 option go_package = "log";
-option java_package = "com.v2ray.core.common.log";
+option java_package = "com.v2ray.core.app.log";
 option java_outer_classname = "ConfigProto";
 
 enum LogType {

+ 0 - 0
common/log/internal/log_entry.go → app/log/internal/log_entry.go


+ 1 - 1
common/log/internal/log_entry_test.go → app/log/internal/log_entry_test.go

@@ -3,7 +3,7 @@ package internal_test
 import (
 	"testing"
 
-	. "v2ray.com/core/common/log/internal"
+	. "v2ray.com/core/app/log/internal"
 	"v2ray.com/core/testing/assert"
 )
 

+ 0 - 0
common/log/internal/log_writer.go → app/log/internal/log_writer.go


+ 0 - 0
common/log/internal/log_writer_test.go → app/log/internal/log_writer_test.go


+ 54 - 2
common/log/log.go → app/log/log.go

@@ -1,8 +1,12 @@
 package log
 
 import (
+	"context"
+
+	"v2ray.com/core/app"
+	"v2ray.com/core/app/log/internal"
+	"v2ray.com/core/common"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log/internal"
 )
 
 var (
@@ -77,7 +81,55 @@ func Error(val ...interface{}) {
 	})
 }
 
-func Close() {
+type Instance struct {
+	config *Config
+}
+
+func New(ctx context.Context, config *Config) (*Instance, error) {
+	return &Instance{config: config}, nil
+}
+
+func (*Instance) Interface() interface{} {
+	return (*Instance)(nil)
+}
+
+func (g *Instance) Start() error {
+	config := g.config
+	if config.AccessLogType == LogType_File {
+		if err := InitAccessLogger(config.AccessLogPath); err != nil {
+			return err
+		}
+	}
+
+	if config.ErrorLogType == LogType_None {
+		SetLogLevel(LogLevel_Disabled)
+	} else {
+		if config.ErrorLogType == LogType_File {
+			if err := InitErrorLogger(config.ErrorLogPath); err != nil {
+				return err
+			}
+		}
+		SetLogLevel(config.ErrorLogLevel)
+	}
+
+	return nil
+}
+
+func (*Instance) Close() {
 	streamLoggerInstance.Close()
 	accessLoggerInstance.Close()
 }
+
+func FromSpace(space app.Space) *Instance {
+	v := space.GetApplication((*Instance)(nil))
+	if logger, ok := v.(*Instance); ok && logger != nil {
+		return logger
+	}
+	return nil
+}
+
+func init() {
+	common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
+		return New(ctx, config.(*Config))
+	}))
+}

+ 1 - 1
app/proxyman/inbound/always.go

@@ -5,7 +5,7 @@ import (
 
 	"v2ray.com/core/app/proxyman"
 	"v2ray.com/core/common/dice"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/proxy"
 )

+ 1 - 1
app/proxyman/inbound/dynamic.go

@@ -7,7 +7,7 @@ import (
 
 	"v2ray.com/core/app/proxyman"
 	"v2ray.com/core/common/dice"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/proxy"
 )

+ 1 - 1
app/proxyman/outbound/handler.go

@@ -10,7 +10,7 @@ import (
 	"v2ray.com/core/app/proxyman"
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/proxy"
 	"v2ray.com/core/transport/internet"

+ 4 - 0
app/proxyman/outbound/outbound.go

@@ -24,6 +24,10 @@ func (DefaultOutboundHandlerManager) Interface() interface{} {
 	return (*proxyman.OutboundHandlerManager)(nil)
 }
 
+func (DefaultOutboundHandlerManager) Start() error { return nil }
+
+func (DefaultOutboundHandlerManager) Close() {}
+
 func (v *DefaultOutboundHandlerManager) GetDefaultHandler() proxyman.OutboundHandler {
 	v.RLock()
 	defer v.RUnlock()

+ 2 - 0
app/proxyman/proxyman.go

@@ -29,6 +29,8 @@ type OutboundHandlerManager interface {
 	GetHandler(tag string) OutboundHandler
 	GetDefaultHandler() OutboundHandler
 	AddHandler(ctx context.Context, config *OutboundHandlerConfig) error
+	Start() error
+	Close()
 }
 
 type OutboundHandler interface {

+ 7 - 1
app/router/router.go

@@ -5,9 +5,9 @@ import (
 
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/dns"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/proxy"
 )
@@ -91,6 +91,12 @@ func (Router) Interface() interface{} {
 	return (*Router)(nil)
 }
 
+func (Router) Start() error {
+	return nil
+}
+
+func (Router) Close() {}
+
 func FromSpace(space app.Space) *Router {
 	app := space.GetApplication((*Router)(nil))
 	if app == nil {

+ 20 - 4
app/space.go

@@ -6,11 +6,12 @@ import (
 
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
 )
 
 type Application interface {
 	Interface() interface{}
+	Start() error
+	Close()
 }
 
 type InitializationCallback func() error
@@ -35,6 +36,8 @@ type Space interface {
 	AddApplication(application Application) error
 	Initialize() error
 	OnInitialize(InitializationCallback)
+	Start() error
+	Close()
 }
 
 type spaceImpl struct {
@@ -52,9 +55,7 @@ func NewSpace() Space {
 
 func (v *spaceImpl) OnInitialize(f InitializationCallback) {
 	if v.initialized {
-		if err := f(); err != nil {
-			log.Error("Space: error after space initialization: ", err)
-		}
+		f()
 	} else {
 		v.appInit = append(v.appInit, f)
 	}
@@ -88,6 +89,21 @@ func (v *spaceImpl) AddApplication(app Application) error {
 	return nil
 }
 
+func (s *spaceImpl) Start() error {
+	for _, app := range s.cache {
+		if err := app.Start(); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (s *spaceImpl) Close() {
+	for _, app := range s.cache {
+		app.Close()
+	}
+}
+
 type contextKey int
 
 const (

+ 1 - 1
common/net/address.go

@@ -3,7 +3,7 @@ package net
 import (
 	"net"
 
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/predicate"
 )
 

+ 22 - 32
config.pb.go

@@ -5,7 +5,6 @@ import fmt "fmt"
 import math "math"
 import v2ray_core_app_proxyman "v2ray.com/core/app/proxyman"
 import v2ray_core_common_serial "v2ray.com/core/common/serial"
-import v2ray_core_common_log "v2ray.com/core/common/log"
 import v2ray_core_transport "v2ray.com/core/transport"
 
 // Reference imports to suppress errors if they are not otherwise used.
@@ -46,7 +45,6 @@ type Config struct {
 	Inbound []*v2ray_core_app_proxyman.InboundHandlerConfig `protobuf:"bytes,1,rep,name=inbound" json:"inbound,omitempty"`
 	// Outbound handler configurations. Must have at least one item. The first item is used as default for routing.
 	Outbound []*v2ray_core_app_proxyman.OutboundHandlerConfig `protobuf:"bytes,2,rep,name=outbound" json:"outbound,omitempty"`
-	Log      *v2ray_core_common_log.Config                    `protobuf:"bytes,3,opt,name=log" json:"log,omitempty"`
 	// App configuration. Must be one in the app directory.
 	App       []*v2ray_core_common_serial.TypedMessage `protobuf:"bytes,4,rep,name=app" json:"app,omitempty"`
 	Transport *v2ray_core_transport.Config             `protobuf:"bytes,5,opt,name=transport" json:"transport,omitempty"`
@@ -71,13 +69,6 @@ func (m *Config) GetOutbound() []*v2ray_core_app_proxyman.OutboundHandlerConfig
 	return nil
 }
 
-func (m *Config) GetLog() *v2ray_core_common_log.Config {
-	if m != nil {
-		return m.Log
-	}
-	return nil
-}
-
 func (m *Config) GetApp() []*v2ray_core_common_serial.TypedMessage {
 	if m != nil {
 		return m.App
@@ -100,27 +91,26 @@ func init() {
 func init() { proto.RegisterFile("v2ray.com/core/config.proto", fileDescriptor0) }
 
 var fileDescriptor0 = []byte{
-	// 338 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x91, 0xdf, 0x4a, 0x02, 0x41,
-	0x14, 0xc6, 0xd3, 0x35, 0xb3, 0xa3, 0x84, 0xcc, 0xd5, 0x62, 0x05, 0x12, 0x24, 0x12, 0x34, 0x2b,
-	0xdb, 0x4d, 0x74, 0xa9, 0xd0, 0x1f, 0xa1, 0x0c, 0x8b, 0x2e, 0xba, 0x89, 0x71, 0x1d, 0x17, 0x61,
-	0x67, 0xce, 0x30, 0xbb, 0x46, 0xfb, 0x4a, 0x3d, 0x47, 0x0f, 0x16, 0x3b, 0xe3, 0xaa, 0x6b, 0x76,
-	0x7b, 0xe6, 0xfb, 0xfd, 0x0e, 0xe7, 0x1b, 0x38, 0xfe, 0xf4, 0x35, 0x4b, 0x69, 0x80, 0xc2, 0x0b,
-	0x50, 0x73, 0x2f, 0x40, 0x39, 0x9b, 0x87, 0x54, 0x69, 0x4c, 0x90, 0x40, 0xfe, 0xa8, 0x79, 0xab,
-	0xbb, 0x15, 0x64, 0x4a, 0x79, 0x4a, 0xe3, 0x57, 0x2a, 0x98, 0x2c, 0x50, 0xad, 0xde, 0x1f, 0xa5,
-	0x10, 0x28, 0xbd, 0x98, 0xeb, 0x39, 0x8b, 0xbc, 0x24, 0x55, 0x7c, 0xfa, 0x21, 0x78, 0x1c, 0xb3,
-	0x90, 0x2f, 0x89, 0xce, 0x6e, 0x22, 0xc2, 0xb0, 0x68, 0x3e, 0xdf, 0xca, 0x25, 0x9a, 0xc9, 0x58,
-	0xa1, 0x4e, 0x0a, 0xb1, 0xb3, 0x9f, 0x32, 0x54, 0x07, 0x66, 0x40, 0xee, 0xe0, 0x60, 0x2e, 0x27,
-	0xb8, 0x90, 0x53, 0xb7, 0xd4, 0x76, 0xba, 0x75, 0xff, 0x92, 0xae, 0x6f, 0xa2, 0x4c, 0x29, 0x9a,
-	0xdf, 0x40, 0x1f, 0x6c, 0xee, 0x9e, 0xc9, 0x69, 0xc4, 0xb5, 0xe5, 0xc7, 0x39, 0x4d, 0x86, 0x50,
-	0xc3, 0x45, 0x62, 0x4d, 0x65, 0x63, 0xa2, 0xff, 0x9a, 0x46, 0xcb, 0x60, 0x51, 0xb5, 0xe2, 0x89,
-	0x07, 0x4e, 0x84, 0xa1, 0xeb, 0xb4, 0x4b, 0xdd, 0xba, 0x7f, 0xba, 0xa9, 0xb1, 0x87, 0xd3, 0x08,
-	0x43, 0xba, 0xa4, 0xb2, 0x24, 0xb9, 0x06, 0x87, 0x29, 0xe5, 0x56, 0xcc, 0xde, 0xce, 0x0e, 0xc0,
-	0x76, 0x4b, 0x5f, 0xb3, 0x6e, 0x1f, 0x6d, 0xb5, 0xe3, 0x0c, 0x21, 0x37, 0x70, 0xb8, 0x2a, 0xc9,
-	0xdd, 0x37, 0x0b, 0x4f, 0x36, 0xf9, 0xd5, 0x63, 0xbe, 0x6f, 0x1d, 0xbf, 0xe8, 0x40, 0xc3, 0x0e,
-	0x6f, 0x51, 0x0b, 0x96, 0x90, 0x06, 0xd4, 0x9e, 0xb3, 0x7e, 0x27, 0x8b, 0x59, 0x73, 0x8f, 0xd4,
-	0xa0, 0x32, 0x7c, 0x19, 0x3d, 0x35, 0x4b, 0xfd, 0x1e, 0x1c, 0x05, 0x28, 0x36, 0xac, 0xfd, 0xba,
-	0xe5, 0x4c, 0xfa, 0xbd, 0x92, 0x8d, 0xbe, 0xcb, 0xf0, 0xe6, 0x8f, 0x59, 0x4a, 0x07, 0xa8, 0xf9,
-	0xa4, 0x6a, 0xfe, 0xe9, 0xea, 0x37, 0x00, 0x00, 0xff, 0xff, 0xa7, 0x35, 0x52, 0xbd, 0x7d, 0x02,
-	0x00, 0x00,
+	// 321 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x90, 0xcd, 0x4a, 0xf3, 0x40,
+	0x14, 0x86, 0xbf, 0xb6, 0xf9, 0x6a, 0x3c, 0x2d, 0x52, 0x66, 0x55, 0xaa, 0x8b, 0x22, 0x58, 0x8a,
+	0xe0, 0xa4, 0xc4, 0x8d, 0xb8, 0x6c, 0xc1, 0x9f, 0x82, 0x56, 0xaa, 0xb8, 0x70, 0x23, 0xd3, 0x74,
+	0x5a, 0x0a, 0x9d, 0x39, 0xc3, 0x64, 0x22, 0xe6, 0x52, 0xbc, 0x05, 0xaf, 0x52, 0x92, 0x49, 0xd2,
+	0xa4, 0xe2, 0xf6, 0x9c, 0xf7, 0x79, 0xe6, 0xcc, 0x0b, 0xc7, 0x1f, 0xbe, 0x66, 0x31, 0x0d, 0x50,
+	0x78, 0x01, 0x6a, 0xee, 0x05, 0x28, 0x57, 0x9b, 0x35, 0x55, 0x1a, 0x0d, 0x12, 0xc8, 0x97, 0x9a,
+	0xf7, 0x86, 0x7b, 0x41, 0xa6, 0x94, 0xa7, 0x34, 0x7e, 0xc6, 0x82, 0xc9, 0x0a, 0xd5, 0x1b, 0xfd,
+	0x52, 0x0a, 0x81, 0xd2, 0x0b, 0xb9, 0xde, 0xb0, 0xad, 0x67, 0x62, 0xc5, 0x97, 0xef, 0x82, 0x87,
+	0x21, 0x5b, 0xf3, 0x8c, 0x38, 0xdb, 0x23, 0x8c, 0x66, 0x32, 0x54, 0xa8, 0x4d, 0x45, 0x7c, 0xfa,
+	0x55, 0x87, 0xe6, 0x24, 0x1d, 0x90, 0x5b, 0x38, 0xd8, 0xc8, 0x05, 0x46, 0x72, 0xd9, 0xad, 0xf5,
+	0x1b, 0xc3, 0x96, 0x7f, 0x41, 0x77, 0xb7, 0x52, 0xa6, 0x14, 0xcd, 0x6f, 0xa3, 0xf7, 0x36, 0x77,
+	0xc7, 0xe4, 0x72, 0xcb, 0xb5, 0xe5, 0xe7, 0x39, 0x4d, 0xa6, 0xe0, 0x62, 0x64, 0xac, 0xa9, 0x9e,
+	0x9a, 0xe8, 0x9f, 0xa6, 0x59, 0x16, 0xac, 0xaa, 0x0a, 0x9e, 0x5c, 0x41, 0x83, 0x29, 0xd5, 0x75,
+	0x52, 0xcd, 0xa0, 0xac, 0xb1, 0x15, 0x50, 0x5b, 0x01, 0x7d, 0x49, 0x2a, 0x78, 0xb0, 0x0d, 0xcc,
+	0x13, 0x84, 0x5c, 0xc3, 0x61, 0xf1, 0xe7, 0xee, 0xff, 0x7e, 0x6d, 0xd8, 0xf2, 0x4f, 0xca, 0x7c,
+	0xb1, 0xa4, 0xd9, 0xa3, 0xbb, 0xf8, 0xd4, 0x71, 0x1b, 0x1d, 0xe7, 0x7c, 0x00, 0x6d, 0xbb, 0xba,
+	0x41, 0x2d, 0x98, 0x21, 0x6d, 0x70, 0x9f, 0x92, 0xd2, 0x16, 0xd1, 0xaa, 0xf3, 0x8f, 0xb8, 0xe0,
+	0x4c, 0x9f, 0x67, 0x8f, 0x9d, 0xda, 0x78, 0x04, 0x47, 0x01, 0x8a, 0x92, 0x7b, 0xdc, 0xb2, 0x5c,
+	0x9a, 0x7e, 0x73, 0x92, 0xd1, 0x77, 0x1d, 0x5e, 0xfd, 0x39, 0x8b, 0xe9, 0x04, 0x35, 0x5f, 0x34,
+	0xd3, 0xf2, 0x2f, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x0b, 0x7e, 0xca, 0x56, 0x2a, 0x02, 0x00,
+	0x00,
 }

+ 1 - 2
config.proto

@@ -8,7 +8,6 @@ option java_outer_classname = "ConfigProto";
 
 import "v2ray.com/core/app/proxyman/config.proto";
 import "v2ray.com/core/common/serial/typed_message.proto";
-import "v2ray.com/core/common/log/config.proto";
 import "v2ray.com/core/transport/config.proto";
 
 // Configuration serialization format.
@@ -24,7 +23,7 @@ message Config {
   // Outbound handler configurations. Must have at least one item. The first item is used as default for routing.
   repeated v2ray.core.app.proxyman.OutboundHandlerConfig outbound = 2;
 
-  v2ray.core.common.log.Config log = 3;
+  reserved 3;
 
   // App configuration. Must be one in the app directory.
   repeated v2ray.core.common.serial.TypedMessage app = 4;

+ 1 - 1
proxy/dokodemo/dokodemo.go

@@ -10,7 +10,7 @@ import (
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/common/signal"
 	"v2ray.com/core/proxy"

+ 1 - 1
proxy/freedom/freedom.go

@@ -12,7 +12,7 @@ import (
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/dice"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/common/retry"
 	"v2ray.com/core/common/signal"

+ 1 - 1
proxy/http/server.go

@@ -17,7 +17,7 @@ import (
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/bufio"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/signal"
 	"v2ray.com/core/proxy"

+ 1 - 1
proxy/shadowsocks/client.go

@@ -10,7 +10,7 @@ import (
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/bufio"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/retry"

+ 1 - 1
proxy/shadowsocks/server.go

@@ -12,7 +12,7 @@ import (
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/bufio"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/signal"

+ 1 - 1
proxy/socks/client.go

@@ -8,7 +8,7 @@ import (
 
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/buf"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/retry"

+ 1 - 1
proxy/socks/server.go

@@ -12,7 +12,7 @@ import (
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/bufio"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/signal"

+ 10 - 1
proxy/vmess/account.go

@@ -2,7 +2,7 @@ package vmess
 
 import (
 	"v2ray.com/core/common/dice"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/uuid"
 )
@@ -42,3 +42,12 @@ func (v *Account) AsAccount() (protocol.Account, error) {
 		Security: v.SecuritySettings.AsSecurity(),
 	}, nil
 }
+
+func (v *Account) GetMultiplexingSettings() *Multiplexing {
+	if v.Mux == nil {
+		return &Multiplexing{
+			Enabled: false,
+		}
+	}
+	return v.Mux
+}

+ 46 - 18
proxy/vmess/account.pb.go

@@ -16,6 +16,22 @@ var _ = math.Inf
 // proto package needs to be updated.
 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
 
+type Multiplexing struct {
+	Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"`
+}
+
+func (m *Multiplexing) Reset()                    { *m = Multiplexing{} }
+func (m *Multiplexing) String() string            { return proto.CompactTextString(m) }
+func (*Multiplexing) ProtoMessage()               {}
+func (*Multiplexing) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+
+func (m *Multiplexing) GetEnabled() bool {
+	if m != nil {
+		return m.Enabled
+	}
+	return false
+}
+
 type Account struct {
 	// ID of the account, in the form of an UUID, e.g., "66ad4540-b58c-4ad2-9926-ea63445a9b57".
 	Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
@@ -23,12 +39,13 @@ type Account struct {
 	AlterId uint32 `protobuf:"varint,2,opt,name=alter_id,json=alterId" json:"alter_id,omitempty"`
 	// Security settings. Only applies to client side.
 	SecuritySettings *v2ray_core_common_protocol.SecurityConfig `protobuf:"bytes,3,opt,name=security_settings,json=securitySettings" json:"security_settings,omitempty"`
+	Mux              *Multiplexing                              `protobuf:"bytes,4,opt,name=mux" json:"mux,omitempty"`
 }
 
 func (m *Account) Reset()                    { *m = Account{} }
 func (m *Account) String() string            { return proto.CompactTextString(m) }
 func (*Account) ProtoMessage()               {}
-func (*Account) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+func (*Account) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
 
 func (m *Account) GetId() string {
 	if m != nil {
@@ -51,28 +68,39 @@ func (m *Account) GetSecuritySettings() *v2ray_core_common_protocol.SecurityConf
 	return nil
 }
 
+func (m *Account) GetMux() *Multiplexing {
+	if m != nil {
+		return m.Mux
+	}
+	return nil
+}
+
 func init() {
+	proto.RegisterType((*Multiplexing)(nil), "v2ray.core.proxy.vmess.Multiplexing")
 	proto.RegisterType((*Account)(nil), "v2ray.core.proxy.vmess.Account")
 }
 
 func init() { proto.RegisterFile("v2ray.com/core/proxy/vmess/account.proto", fileDescriptor0) }
 
 var fileDescriptor0 = []byte{
-	// 250 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x6c, 0x8f, 0x4f, 0x4b, 0xc3, 0x30,
-	0x18, 0xc6, 0x49, 0x45, 0xa7, 0xf1, 0x0f, 0xda, 0xc3, 0xa8, 0x3b, 0x15, 0x4f, 0x45, 0xe4, 0x0d,
-	0xd4, 0x4f, 0xe0, 0x76, 0xd2, 0xd3, 0xe8, 0x60, 0x82, 0x97, 0x11, 0x93, 0x38, 0x03, 0x4b, 0xdf,
-	0xf1, 0x26, 0x1b, 0xf6, 0x43, 0xf8, 0x45, 0xfc, 0x94, 0xd2, 0xb4, 0x05, 0x91, 0x1d, 0x93, 0xfc,
-	0x9e, 0xdf, 0xf3, 0x84, 0x17, 0xfb, 0x92, 0x64, 0x03, 0x0a, 0x9d, 0x50, 0x48, 0x46, 0x6c, 0x09,
-	0xbf, 0x1a, 0xb1, 0x77, 0xc6, 0x7b, 0x21, 0x95, 0xc2, 0x5d, 0x1d, 0x60, 0x4b, 0x18, 0x30, 0x1d,
-	0x0f, 0x24, 0x19, 0x88, 0x14, 0x44, 0x6a, 0xf2, 0xf0, 0xcf, 0xa0, 0xd0, 0x39, 0xac, 0x45, 0x0c,
-	0x29, 0xdc, 0x88, 0x4f, 0x23, 0xb5, 0x21, 0xdf, 0x59, 0xee, 0xbe, 0x19, 0x1f, 0x3d, 0x75, 0xde,
-	0xf4, 0x8a, 0x27, 0x56, 0x67, 0x2c, 0x67, 0xc5, 0x59, 0x95, 0x58, 0x9d, 0xde, 0xf2, 0x53, 0xb9,
-	0x09, 0x86, 0x56, 0x56, 0x67, 0x49, 0xce, 0x8a, 0xcb, 0x6a, 0x14, 0xcf, 0xcf, 0x3a, 0x7d, 0xe5,
-	0x37, 0xde, 0xa8, 0x1d, 0xd9, 0xd0, 0xac, 0xbc, 0x09, 0xc1, 0xd6, 0x6b, 0x9f, 0x1d, 0xe5, 0xac,
-	0x38, 0x2f, 0xef, 0xe1, 0xcf, 0xb0, 0xae, 0x1c, 0x86, 0x72, 0x58, 0xf4, 0xa1, 0x19, 0xd6, 0x1f,
-	0x76, 0x5d, 0x5d, 0x0f, 0x92, 0x45, 0xef, 0x98, 0xbe, 0xf0, 0x89, 0x42, 0x07, 0x87, 0xff, 0x36,
-	0xbd, 0xe8, 0xa7, 0xce, 0x5b, 0xdf, 0xdb, 0x71, 0xbc, 0xfc, 0x49, 0xc6, 0xcb, 0xb2, 0x92, 0x0d,
-	0xcc, 0x5a, 0x7a, 0x1e, 0xe9, 0x65, 0xfb, 0xf0, 0x7e, 0x12, 0x6b, 0x1f, 0x7f, 0x03, 0x00, 0x00,
-	0xff, 0xff, 0x5d, 0x45, 0x43, 0x16, 0x54, 0x01, 0x00, 0x00,
+	// 295 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x90, 0x41, 0x4b, 0xf3, 0x30,
+	0x1c, 0xc6, 0x69, 0xf7, 0xbe, 0x6e, 0xc6, 0x29, 0x9a, 0xc3, 0xa8, 0x3b, 0x95, 0xe1, 0xa1, 0x88,
+	0x24, 0x50, 0xc1, 0xbb, 0xdb, 0x49, 0x41, 0x18, 0x19, 0x4c, 0xf0, 0x32, 0xb2, 0x34, 0xd6, 0x40,
+	0x93, 0x94, 0x24, 0x1d, 0xed, 0x57, 0xf2, 0x7b, 0xf8, 0xbd, 0xa4, 0x69, 0x0b, 0x43, 0xf4, 0xf8,
+	0x6f, 0x7f, 0xcf, 0xc3, 0xef, 0x09, 0x48, 0x0e, 0xa9, 0xa1, 0x0d, 0x62, 0x5a, 0x62, 0xa6, 0x0d,
+	0xc7, 0xa5, 0xd1, 0x75, 0x83, 0x0f, 0x92, 0x5b, 0x8b, 0x29, 0x63, 0xba, 0x52, 0x0e, 0x95, 0x46,
+	0x3b, 0x0d, 0x67, 0x03, 0x69, 0x38, 0xf2, 0x14, 0xf2, 0xd4, 0xfc, 0xee, 0x47, 0x03, 0xd3, 0x52,
+	0x6a, 0x85, 0x7d, 0x88, 0xe9, 0x02, 0x7f, 0x70, 0x9a, 0x71, 0x63, 0xbb, 0x96, 0x45, 0x02, 0xa6,
+	0x2f, 0x55, 0xe1, 0x44, 0x59, 0xf0, 0x5a, 0xa8, 0x1c, 0x46, 0x60, 0xcc, 0x15, 0xdd, 0x17, 0x3c,
+	0x8b, 0x82, 0x38, 0x48, 0x26, 0x64, 0x38, 0x17, 0x5f, 0x01, 0x18, 0x3f, 0x76, 0x06, 0xf0, 0x02,
+	0x84, 0xa2, 0x03, 0x4e, 0x49, 0x28, 0x32, 0x78, 0x0d, 0x26, 0xb4, 0x70, 0xdc, 0xec, 0x44, 0x16,
+	0x85, 0x71, 0x90, 0x9c, 0x93, 0xb1, 0xbf, 0x9f, 0x32, 0xf8, 0x0a, 0xae, 0x2c, 0x67, 0x95, 0x11,
+	0xae, 0xd9, 0x59, 0xee, 0x9c, 0x50, 0xb9, 0x8d, 0x46, 0x71, 0x90, 0x9c, 0xa5, 0xb7, 0xe8, 0x68,
+	0x42, 0xa7, 0x89, 0x06, 0x4d, 0xb4, 0xe9, 0x43, 0x2b, 0xad, 0xde, 0x45, 0x4e, 0x2e, 0x87, 0x92,
+	0x4d, 0xdf, 0x01, 0x1f, 0xc0, 0x48, 0x56, 0x75, 0xf4, 0xcf, 0x57, 0xdd, 0xa0, 0xdf, 0x5f, 0x03,
+	0x1d, 0x8f, 0x23, 0x6d, 0x60, 0xf9, 0x0c, 0xe6, 0x4c, 0xcb, 0x3f, 0xf8, 0xe5, 0xb4, 0x9f, 0xb8,
+	0x6e, 0x3d, 0xde, 0xfe, 0xfb, 0x8f, 0x9f, 0xe1, 0x6c, 0x9b, 0x12, 0xda, 0xa0, 0x55, 0x4b, 0xaf,
+	0x3d, 0xbd, 0x6d, 0x7f, 0xec, 0x4f, 0xbc, 0xee, 0xfd, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x90,
+	0xcb, 0xba, 0xdd, 0xb6, 0x01, 0x00, 0x00,
 }

+ 6 - 0
proxy/vmess/account.proto

@@ -8,6 +8,10 @@ option java_outer_classname = "AccountProto";
 
 import "v2ray.com/core/common/protocol/headers.proto";
 
+message Multiplexing {
+  bool enabled = 1;
+}
+
 message Account {
   // ID of the account, in the form of an UUID, e.g., "66ad4540-b58c-4ad2-9926-ea63445a9b57".
   string id = 1;
@@ -15,4 +19,6 @@ message Account {
   uint32 alter_id = 2;
   // Security settings. Only applies to client side.
   v2ray.core.common.protocol.SecurityConfig security_settings = 3;
+
+  Multiplexing mux = 4;
 }

+ 1 - 1
proxy/vmess/encoding/client.go

@@ -14,7 +14,7 @@ import (
 	"v2ray.com/core/common/crypto"
 	"v2ray.com/core/common/dice"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/serial"

+ 1 - 1
proxy/vmess/encoding/server.go

@@ -12,7 +12,7 @@ import (
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/crypto"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/serial"

+ 1 - 1
proxy/vmess/inbound/inbound.go

@@ -15,7 +15,7 @@ import (
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/bufio"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/serial"

+ 1 - 1
proxy/vmess/outbound/outbound.go

@@ -10,7 +10,7 @@ import (
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/bufio"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 	"v2ray.com/core/common/retry"

+ 1 - 1
testing/scenarios/server_env.go

@@ -7,7 +7,7 @@ import (
 	"runtime"
 	"time"
 
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 
 	"fmt"
 	"io/ioutil"

+ 1 - 1
tools/conf/common.go

@@ -5,7 +5,7 @@ import (
 	"strings"
 
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/protocol"
 )

+ 1 - 1
tools/conf/loader.go

@@ -4,7 +4,7 @@ import (
 	"encoding/json"
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 )
 
 var (

+ 1 - 1
tools/conf/log.go

@@ -3,7 +3,7 @@ package conf
 import (
 	"strings"
 
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 )
 
 type LogConfig struct {

+ 1 - 1
tools/conf/router.go

@@ -7,7 +7,7 @@ import (
 
 	"v2ray.com/core/app/router"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/tools/geoip"
 

+ 1 - 1
tools/conf/v2ray.go

@@ -294,7 +294,7 @@ func (v *Config) Build() (*core.Config, error) {
 	config := new(core.Config)
 
 	if v.LogConfig != nil {
-		config.Log = v.LogConfig.Build()
+		config.App = append(config.App, serial.ToTypedMessage(v.LogConfig.Build()))
 	}
 
 	if v.Transport != nil {

+ 1 - 1
transport/internet/kcp/connection.go

@@ -8,7 +8,7 @@ import (
 	"time"
 
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/predicate"
 	"v2ray.com/core/transport/internet/internal"
 )

+ 1 - 1
transport/internet/kcp/dialer.go

@@ -12,7 +12,7 @@ import (
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/dice"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"
 	"v2ray.com/core/transport/internet/internal"

+ 1 - 1
transport/internet/kcp/listener.go

@@ -11,7 +11,7 @@ import (
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"
 	"v2ray.com/core/transport/internet/internal"

+ 1 - 1
transport/internet/tcp/dialer.go

@@ -7,7 +7,7 @@ import (
 
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"
 	"v2ray.com/core/transport/internet/internal"

+ 1 - 1
transport/internet/tcp/hub.go

@@ -8,7 +8,7 @@ import (
 
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"
 	"v2ray.com/core/transport/internet/internal"

+ 1 - 1
transport/internet/tcp/sockopt_linux.go

@@ -5,7 +5,7 @@ package tcp
 import (
 	"syscall"
 
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"
 )

+ 1 - 1
transport/internet/tcp_hub.go

@@ -5,7 +5,7 @@ import (
 	"sync"
 
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/retry"
 )

+ 1 - 1
transport/internet/tls/config.go

@@ -3,7 +3,7 @@ package tls
 import (
 	"crypto/tls"
 
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 )
 
 var (

+ 1 - 1
transport/internet/udp/dispatcher.go

@@ -6,7 +6,7 @@ import (
 
 	"v2ray.com/core/app/dispatcher"
 	"v2ray.com/core/common/buf"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/proxy"
 	"v2ray.com/core/transport/ray"

+ 1 - 1
transport/internet/udp/hub.go

@@ -6,7 +6,7 @@ import (
 
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/dice"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/common/signal"
 	"v2ray.com/core/transport/internet/internal"

+ 1 - 1
transport/internet/websocket/dialer.go

@@ -7,7 +7,7 @@ import (
 
 	"github.com/gorilla/websocket"
 	"v2ray.com/core/common"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"
 	"v2ray.com/core/transport/internet/internal"

+ 1 - 1
transport/internet/websocket/hub.go

@@ -10,7 +10,7 @@ import (
 
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"
 	v2tls "v2ray.com/core/transport/internet/tls"

+ 1 - 1
transport/internet/websocket/wsconn.go

@@ -9,7 +9,7 @@ import (
 
 	"github.com/gorilla/websocket"
 	"v2ray.com/core/common/errors"
-	"v2ray.com/core/common/log"
+	"v2ray.com/core/app/log"
 )
 
 type wsconn struct {

+ 30 - 23
v2ray.go

@@ -6,8 +6,8 @@ import (
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/dispatcher"
 	"v2ray.com/core/app/dns"
+	"v2ray.com/core/app/log"
 	"v2ray.com/core/app/proxyman"
-	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 )
 
@@ -25,15 +25,38 @@ func NewPoint(pConfig *Config) (*Point, error) {
 		return nil, err
 	}
 
-	if err := pConfig.Log.Apply(); err != nil {
-		return nil, err
-	}
-
 	space := app.NewSpace()
 	ctx := app.ContextWithSpace(context.Background(), space)
 
 	vpoint.space = space
 
+	for _, appSettings := range pConfig.App {
+		settings, err := appSettings.GetInstance()
+		if err != nil {
+			return nil, err
+		}
+		application, err := app.CreateAppFromConfig(ctx, settings)
+		if err != nil {
+			return nil, err
+		}
+		if err := space.AddApplication(application); err != nil {
+			return nil, err
+		}
+	}
+
+	logger := log.FromSpace(space)
+	if logger == nil {
+		l, err := app.CreateAppFromConfig(ctx, &log.Config{
+			ErrorLogType:  log.LogType_Console,
+			ErrorLogLevel: log.LogLevel_Warning,
+			AccessLogType: log.LogType_None,
+		})
+		if err != nil {
+			return nil, err
+		}
+		space.AddApplication(l)
+	}
+
 	outboundHandlerManager := proxyman.OutboundHandlerManagerFromSpace(space)
 	if outboundHandlerManager == nil {
 		o, err := app.CreateAppFromConfig(ctx, new(proxyman.OutboundConfig))
@@ -54,20 +77,6 @@ func NewPoint(pConfig *Config) (*Point, error) {
 		inboundHandlerManager = o.(proxyman.InboundHandlerManager)
 	}
 
-	for _, appSettings := range pConfig.App {
-		settings, err := appSettings.GetInstance()
-		if err != nil {
-			return nil, err
-		}
-		application, err := app.CreateAppFromConfig(ctx, settings)
-		if err != nil {
-			return nil, err
-		}
-		if err := space.AddApplication(application); err != nil {
-			return nil, err
-		}
-	}
-
 	dnsServer := dns.FromSpace(space)
 	if dnsServer == nil {
 		dnsConfig := &dns.Config{
@@ -113,15 +122,13 @@ func NewPoint(pConfig *Config) (*Point, error) {
 }
 
 func (v *Point) Close() {
-	ihm := proxyman.InboundHandlerManagerFromSpace(v.space)
-	ihm.Close()
+	v.space.Close()
 }
 
 // Start starts the Point server, and return any error during the process.
 // In the case of any errors, the state of the server is unpredicatable.
 func (v *Point) Start() error {
-	ihm := proxyman.InboundHandlerManagerFromSpace(v.space)
-	if err := ihm.Start(); err != nil {
+	if err := v.space.Start(); err != nil {
 		return err
 	}
 	log.Warning("V2Ray started.")