Skip to content

Commit

Permalink
WIP: add logger
Browse files Browse the repository at this point in the history
  • Loading branch information
kaveh-ahangar committed Jul 25, 2023
1 parent f5829a6 commit 7b06b82
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 40 deletions.
5 changes: 5 additions & 0 deletions cmd/bepass/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package main

import (
"bepass/doh"
"bepass/logger"
"bepass/server"
"bepass/socks5"
"fmt"
"log"
"os"
"strings"
"time"
Expand Down Expand Up @@ -75,6 +77,8 @@ func main() {
} else {
config.ResolveSystem = "DNSCrypt"
}
stdLogger := log.New(os.Stderr, "", log.Ldate|log.Ltime)
appLogger := logger.NewLogger(stdLogger)

serverHandler := &server.Server{
TLSHeaderLength: config.TLSHeaderLength,
Expand All @@ -88,6 +92,7 @@ func main() {
Cache: cache,
ResolveSystem: config.ResolveSystem,
DoHClient: config.DoHClient,
Logger: appLogger,
}

s5 := socks5.NewServer(
Expand Down
159 changes: 159 additions & 0 deletions logger/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package logger

import (
"fmt"
"log"
"time"
)

// Logger is used to provide debug logger
type Logger interface {
Errorf(format string, args ...interface{})
Error(args ...interface{})
Info(args ...interface{})
Infof(format string, args ...interface{})
Debug(args ...interface{})
Debugf(format string, args ...interface{})
Warn(args ...interface{})
Warnf(format string, args ...interface{})
Fatal(args ...interface{})
Fatalf(format string, args ...interface{})
Panic(args ...interface{})
}

// Std represents a standard logger
type Std struct {
*log.Logger
}

// NewLogger creates a new standard logger with log.Logger
func NewLogger(l *log.Logger) *Std {
return &Std{l}
}

// logLevel represents the log level
type logLevel int

const (
logLevelError logLevel = iota
logLevelInfo
logLevelDebug
logLevelWarn
logLevelFatal
logLevelPanic
)

// logLevelColors represents the ANSI color codes for log levels
var logLevelColors = map[logLevel]string{
logLevelError: "\033[31m", // Red
logLevelInfo: "\033[0m", // Default
logLevelDebug: "\033[36m", // Cyan
logLevelWarn: "\033[33m", // Yellow
logLevelFatal: "\033[31m", // Red
logLevelPanic: "\033[35m", // Magenta
}

// logLevelNames represents the names of log levels
var logLevelNames = map[logLevel]string{
logLevelError: "E",
logLevelInfo: "I",
logLevelDebug: "D",
logLevelWarn: "W",
logLevelFatal: "F",
logLevelPanic: "P",
}

// logMessage represents a log message
type logMessage struct {
level logLevel
message string
}

// logf logs a formatted message with a log level
func (sf Std) logf(level logLevel, format string, args ...interface{}) {
msg := logMessage{
level: level,
message: fmt.Sprintf(format, args...),
}
sf.log(msg)
}

// log logs a message with a log level
func (sf Std) loge(level logLevel, args ...interface{}) {
msg := logMessage{
level: level,
message: fmt.Sprint(args...),
}
sf.log(msg)
}

// log logs a log message
func (sf Std) log(msg logMessage) {
logTime := time.Now().Format("2006-01-02 15:04:05")
levelColor := logLevelColors[msg.level]
levelName := logLevelNames[msg.level]

logFormat := "%s [%s]: %s\033[0m"

sf.Printf(logFormat, logTime, levelColor+levelName, msg.message)
}

// Errorf implements the Logger interface for formatted error messages
func (sf Std) Errorf(format string, args ...interface{}) {
sf.logf(logLevelError, format, args...)
}

// Error implements the Logger interface for error messages
func (sf Std) Error(args ...interface{}) {
sf.loge(logLevelError, args...)
}

// Infof implements the Logger interface for formatted info messages
func (sf Std) Infof(format string, args ...interface{}) {
sf.logf(logLevelInfo, format, args...)
}

// Info implements the Logger interface for info messages
func (sf Std) Info(args ...interface{}) {
sf.loge(logLevelInfo, args...)
}

// Debugf implements the Logger interface for formatted debug messages
func (sf Std) Debugf(format string, args ...interface{}) {
sf.logf(logLevelDebug, format, args...)
}

// Debug implements the Logger interface for debug messages
func (sf Std) Debug(args ...interface{}) {
sf.loge(logLevelDebug, args...)
}

// Warnf implements the Logger interface for formatted warning messages
func (sf Std) Warnf(format string, args ...interface{}) {
sf.logf(logLevelWarn, format, args...)
}

// Warn implements the Logger interface for warning messages
func (sf Std) Warn(args ...interface{}) {
sf.loge(logLevelWarn, args...)
}

// Fatalf implements the Logger interface for formatted fatal messages
func (sf Std) Fatalf(format string, args ...interface{}) {
sf.logf(logLevelFatal, format, args...)
}

// Fatal implements the Logger interface for fatal messages
func (sf Std) Fatal(args ...interface{}) {
sf.loge(logLevelFatal, args...)
}

// Panicf implements the Logger interface for formatted panicmessages
func (sf Std) Panicf(format string, args ...interface{}) {
sf.logf(logLevelPanic, format, args...)
}

// Panic implements the Logger interface for panic messages
func (sf Std) Panic(args ...interface{}) {
sf.loge(logLevelPanic, args...)
}
22 changes: 12 additions & 10 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package server

import (
"bepass/doh"
"bepass/logger"
"bepass/socks5"
"bepass/socks5/statute"
"bytes"
Expand Down Expand Up @@ -31,17 +32,18 @@ type Server struct {
SniChunksLength [2]int
ChunksLengthAfterSni [2]int
DelayBetweenChunks [2]int
Logger *logger.Std
}

func (s *Server) getChunkedPackets(data []byte) map[int][]byte {
chunks := make(map[int][]byte)
hostname, err := s.getHostname(data)
if err != nil {
fmt.Println(err)
s.Logger.Errorf("get hostname error, %v", err)
chunks[0] = data
return chunks
}
fmt.Println("Hostname", string(hostname))
s.Logger.Printf("Hostname %s", string(hostname))
index := bytes.Index(data, hostname)
if index == -1 {
return nil
Expand Down Expand Up @@ -287,7 +289,7 @@ func (s *Server) Handle(socksCtx context.Context, writer io.Writer, socksRequest
if dest.FQDN != "" {
ip, err := s.resolve(dest.FQDN, dohClient)
if err != nil {
fmt.Printf("resolve error, %v\n", err)
s.Logger.Errorf("resolve error, %v", err)
if err := socks5.SendReply(writer, statute.RepHostUnreachable, nil); err != nil {
return fmt.Errorf("failed to send reply, %v", err)
}
Expand All @@ -297,21 +299,21 @@ func (s *Server) Handle(socksCtx context.Context, writer io.Writer, socksRequest
dialDest = ip + ":" + strconv.Itoa(dest.Port)
}
} else {
fmt.Println("no need to resolve", socksRequest.RawDestAddr)
s.Logger.Printf("no need to resolve %s", socksRequest.RawDestAddr)
}
if err := socks5.SendReply(writer, statute.RepSuccess, nil); err != nil {
fmt.Printf("failed to send reply, %v\n", err)
s.Logger.Errorf("failed to send reply, %v", err)
return fmt.Errorf("failed to send reply, %v", err)
}
fmt.Println(dialDest)
s.Logger.Printf("dialing %s", dialDest)
rAddr, err := net.ResolveTCPAddr("tcp", dialDest)
if err != nil {
panic(err)
}

rConn, err := net.DialTCP("tcp", nil, rAddr)
if err != nil {
fmt.Println("unable to connect to", dialDest)
s.Logger.Errorf("unable to connect to %s, %v", dialDest, err)
return err
}
err = rConn.SetNoDelay(true)
Expand All @@ -330,7 +332,7 @@ func (s *Server) resolve(fqdn string, dohClient *doh.Client) (string, error) {
fqdn += "."
}
if s.Cache.Get(fqdn) != nil {
fmt.Println("use dns cache")
s.Logger.Printf("use dns cache")
return s.Cache.Get(fqdn).Value(), nil
}
// Create a DNS request
Expand All @@ -357,11 +359,11 @@ func (s *Server) resolve(fqdn string, dohClient *doh.Client) (string, error) {
}

if err != nil {
fmt.Println(err)
s.Logger.Errorf("resolve error, %v", err)
return "", err
}

fmt.Println(exchange.Answer[0])
s.Logger.Printf("resolve %s to %s", fqdn, exchange.Answer[0].String())
record := strings.Fields(exchange.Answer[0].String())
ttl, err := strconv.Atoi(record[1])
if err != nil {
Expand Down
25 changes: 0 additions & 25 deletions socks5/logger.go

This file was deleted.

5 changes: 3 additions & 2 deletions socks5/option.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package socks5

import (
"bepass/bufferpool"
"bepass/logger"
"context"
"io"
"net"
"bepass/bufferpool"
)

// Option user's option
Expand Down Expand Up @@ -73,7 +74,7 @@ func WithBindIP(ip net.IP) Option {

// WithLogger can be used to provide a custom log target.
// Defaults to io.Discard.
func WithLogger(l Logger) Option {
func WithLogger(l logger.Logger) Option {
return func(s *Server) {
s.logger = l
}
Expand Down
11 changes: 8 additions & 3 deletions socks5/server.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package socks5

import (
"bepass/bufferpool"
"bufio"
"context"
"errors"
"fmt"
"io"
"log"
"net"
"bepass/bufferpool"
"os"

"bepass/socks5/statute"

"bepass/logger"
)

// GPool is used to implement custom goroutine pool default use goroutine
Expand Down Expand Up @@ -43,7 +46,7 @@ type Server struct {
bindIP net.IP
// logger can be used to provide a custom log target.
// Defaults to io.Discard.
logger Logger
logger logger.Logger
// Optional function for dialing out
dial func(ctx context.Context, network, addr string) (net.Conn, error)
// buffer pool
Expand All @@ -58,12 +61,14 @@ type Server struct {

// NewServer creates a new Server
func NewServer(opts ...Option) *Server {
stdLogger := log.New(os.Stderr, "socksLogger", log.Ldate|log.Ltime)
socksLogger := logger.NewLogger(stdLogger)
srv := &Server{
authMethods: []Authenticator{},
bufferPool: bufferpool.NewPool(32 * 1024),
resolver: DNSResolver{},
rules: NewPermitAll(),
logger: NewLogger(log.New(io.Discard, "socks5: ", log.LstdFlags)),
logger: socksLogger,
dial: func(ctx context.Context, net_, addr string) (net.Conn, error) {
return net.Dial(net_, addr)
},
Expand Down

0 comments on commit 7b06b82

Please sign in to comment.