From fc80d5e2792a494352650b10c13f9f5db24ae71d Mon Sep 17 00:00:00 2001 From: V2Ray Date: Fri, 9 Oct 2015 17:43:27 +0200 Subject: [PATCH] Access log --- common/log/access.go | 77 ++++++++++++++++++++++++ config/config.go | 5 ++ config/json/json.go | 13 ++++ proxy/vmess/vmessin.go | 2 + release/config/vpoint_socks_vmess.json | 3 + release/config/vpoint_vmess_freedom.json | 3 + release/server/main.go | 4 ++ 7 files changed, 107 insertions(+) create mode 100644 common/log/access.go diff --git a/common/log/access.go b/common/log/access.go new file mode 100644 index 000000000..76b05a881 --- /dev/null +++ b/common/log/access.go @@ -0,0 +1,77 @@ +package log + +import ( + "log" + "os" +) + +type AccessStatus string + +const ( + AccessAccepted = AccessStatus("accepted") + AccessRejected = AccessStatus("rejected") +) + +type accessLogger interface { + Log(from, to string, status AccessStatus, reason string) +} + +type noOpAccessLogger struct { +} + +func (logger *noOpAccessLogger) Log(from, to string, status AccessStatus, reason string) { + // Swallow +} + +type accessLog struct { + From string + To string + Status AccessStatus + Reason string +} + +type fileAccessLogger struct { + queue chan *accessLog + logger *log.Logger +} + +func (logger *fileAccessLogger) Log(from, to string, status AccessStatus, reason string) { + logger.queue <- &accessLog{ + From: from, + To: to, + Status: status, + Reason: reason, + } +} + +func (logger *fileAccessLogger) Run() { + for entry := range logger.queue { + logger.logger.Println(entry.From + " " + string(entry.Status) + " " + entry.To + " " + entry.Reason) + } +} + +func newFileAccessLogger(path string) accessLogger { + file, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) + if err != nil { + log.Printf("Unable to create or open file (%s): %v\n", path, err) + return nil + } + return &fileAccessLogger{ + queue: make(chan *accessLog, 16), + logger: log.New(file, "", log.Ldate|log.Ltime), + } +} + +var accessLoggerInstance accessLogger = &noOpAccessLogger{} + +func InitAccessLogger(file string) { + logger := newFileAccessLogger(file) + if logger != nil { + go logger.(*fileAccessLogger).Run() + accessLoggerInstance = logger + } +} + +func Access(from, to string, status AccessStatus, reason string) { + accessLoggerInstance.Log(from, to, status, reason) +} diff --git a/config/config.go b/config/config.go index 6f8237e9c..37a8eb37e 100644 --- a/config/config.go +++ b/config/config.go @@ -12,8 +12,13 @@ type ConnectionConfig interface { Settings(configType Type) interface{} } +type LogConfig interface { + AccessLog() string +} + type PointConfig interface { Port() uint16 + LogConfig() LogConfig InboundConfig() ConnectionConfig OutboundConfig() ConnectionConfig } diff --git a/config/json/json.go b/config/json/json.go index 166643355..886e52d78 100644 --- a/config/json/json.go +++ b/config/json/json.go @@ -32,9 +32,18 @@ func (config *ConnectionConfig) Settings(configType config.Type) interface{} { return configObj } +type LogConfig struct { + AccessLogValue string `json:"access"` +} + +func (config *LogConfig) AccessLog() string { + return config.AccessLogValue +} + // Config is the config for Point server. type Config struct { PortValue uint16 `json:"port"` // Port of this Point server. + LogConfigValue *LogConfig `json:"log"` InboundConfigValue *ConnectionConfig `json:"inbound"` OutboundConfigValue *ConnectionConfig `json:"outbound"` } @@ -43,6 +52,10 @@ func (config *Config) Port() uint16 { return config.PortValue } +func (config *Config) LogConfig() config.LogConfig { + return config.LogConfigValue +} + func (config *Config) InboundConfig() config.ConnectionConfig { return config.InboundConfigValue } diff --git a/proxy/vmess/vmessin.go b/proxy/vmess/vmessin.go index c4ae3e1a6..d7b86eb84 100644 --- a/proxy/vmess/vmessin.go +++ b/proxy/vmess/vmessin.go @@ -68,9 +68,11 @@ func (handler *VMessInboundHandler) HandleConnection(connection *net.TCPConn) er request, err := requestReader.Read(connReader) if err != nil { + log.Access(connection.RemoteAddr().String(), "", log.AccessRejected, "Invalid Auth") log.Warning("VMessIn: Invalid request from (%s): %v", connection.RemoteAddr().String(), err) return err } + log.Access(connection.RemoteAddr().String(), request.Address.String(), log.AccessAccepted, "") log.Debug("VMessIn: Received request for %s", request.Address.String()) ray := handler.vPoint.DispatchToOutbound(v2net.NewPacket(request.Destination(), nil, true)) diff --git a/release/config/vpoint_socks_vmess.json b/release/config/vpoint_socks_vmess.json index fce0dfc8e..a654a0908 100644 --- a/release/config/vpoint_socks_vmess.json +++ b/release/config/vpoint_socks_vmess.json @@ -1,5 +1,8 @@ { "port": 1080, + "log": { + "access": "" + }, "inbound": { "protocol": "socks", "settings": { diff --git a/release/config/vpoint_vmess_freedom.json b/release/config/vpoint_vmess_freedom.json index 4351b991e..011ed6076 100644 --- a/release/config/vpoint_vmess_freedom.json +++ b/release/config/vpoint_vmess_freedom.json @@ -1,5 +1,8 @@ { "port": 27183, + "log" : { + "access": "./access.log" + }, "inbound": { "protocol": "vmess", "settings": { diff --git a/release/server/main.go b/release/server/main.go index 4e0d65ff6..6a7d11f48 100644 --- a/release/server/main.go +++ b/release/server/main.go @@ -55,6 +55,10 @@ func main() { return } + if config.LogConfig() != nil && len(config.LogConfig().AccessLog()) > 0 { + log.InitAccessLogger(config.LogConfig().AccessLog()) + } + vPoint, err := core.NewPoint(config) if err != nil { log.Error("Failed to create Point server: %v", err)