97 lines
2.1 KiB
Go
97 lines
2.1 KiB
Go
package ports
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
"time"
|
|
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type Server struct {
|
|
EnabledPortsTCP []string
|
|
EnabledPortsUDP []string
|
|
IP string
|
|
Logger *zap.SugaredLogger
|
|
|
|
store Store
|
|
}
|
|
|
|
func New(store Store) *Server {
|
|
return &Server{store: store, Logger: zap.NewNop().Sugar()}
|
|
}
|
|
|
|
func (s *Server) Start(ctx context.Context) error {
|
|
for _, port := range s.EnabledPortsTCP {
|
|
portCtx, cancel := context.WithCancel(ctx)
|
|
go s.doListenTCP(portCtx, port)
|
|
defer cancel()
|
|
}
|
|
|
|
<-ctx.Done()
|
|
return nil
|
|
}
|
|
|
|
func (s *Server) AddTCPPort(port string) {
|
|
s.EnabledPortsTCP = append(s.EnabledPortsTCP, port)
|
|
}
|
|
|
|
func (s *Server) doListenTCP(ctx context.Context, port string) error {
|
|
lAddr, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(s.IP, port))
|
|
if err != nil {
|
|
s.Logger.Warnw("Error resoling listening addr.", "network", "tcp", "port", port)
|
|
return fmt.Errorf("error resolving listening address: %w", err)
|
|
}
|
|
|
|
listener, err := net.ListenTCP("tcp", lAddr)
|
|
if err != nil {
|
|
return fmt.Errorf("error starting listener: %w", err)
|
|
}
|
|
defer listener.Close()
|
|
|
|
go func() {
|
|
<-ctx.Done()
|
|
s.Logger.Debug("Listener context cancelled.")
|
|
listener.Close()
|
|
}()
|
|
|
|
s.Logger.Infow("Listening for connections to TCP port.", "port", port)
|
|
for {
|
|
conn, err := listener.Accept()
|
|
if err != nil {
|
|
select {
|
|
case <-ctx.Done():
|
|
s.Logger.Infow("Listener shutting down.", "port", port, "network", "tcp")
|
|
return nil
|
|
default:
|
|
s.Logger.Infow("Error accepting connection.", "error", err)
|
|
continue
|
|
}
|
|
}
|
|
|
|
s.Logger.Infow("Got connection on port.", "port", port, "network", "tcp", "remote_addr", conn.RemoteAddr().String())
|
|
|
|
conn.SetReadDeadline(time.Now().Add(time.Second * 15))
|
|
|
|
buf := make([]byte, 256)
|
|
|
|
_, err = conn.Read(buf)
|
|
if err != nil {
|
|
buf = []byte{}
|
|
}
|
|
|
|
attempt := &ConnectionAttempt{
|
|
Port: port,
|
|
Network: "tcp",
|
|
From: conn.RemoteAddr().String(),
|
|
Data: buf,
|
|
}
|
|
conn.Close()
|
|
|
|
if err := s.store.Add(attempt); err != nil {
|
|
s.Logger.Warnw("Error storing attempt in store.", "error", err)
|
|
}
|
|
}
|
|
}
|