Created
February 24, 2024 13:56
-
-
Save rafkatg/c8b5d233d003fae9c17aa0a4a6df92d9 to your computer and use it in GitHub Desktop.
Revisions
-
rafkatg created this gist
Feb 24, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,90 @@ package main import ( "log" "net" "sync" "time" ) const ( maxRequestsPerIP = 100 // Limit requests from each IP address maxConnectionsPerIP = 5 // Limit connections from each IP address ) type request struct { ip net.IP request chan *net.UDPConn } type server struct { requests map[string]*request requestMutex sync.Mutex connections map[string]int } func NewServer() *server { return &server{ requests: make(map[string]*request), requestMutex: sync.Mutex{}, connections: make(map[string]int), } } func (s *server) ServeUDP(conn *net.UDPConn, addr net.Addr) error { s.requestMutex.Lock() defer s.requestMutex.Unlock() ip := addr.IP if _, exists := s.connections[ip]; exists { s.connections[ip]++ if s.connections[ip] > maxConnectionsPerIP { log.Printf("Connection limit exceeded for IP: %s", ip) conn.Close() return nil } } else { s.connections[ip] = 1 } s.requestMutex.Unlock() request := &request{ ip: ip, request: make(chan *net.UDPConn, maxRequestsPerIP)), } s.requests[ip] = request go s.handleRequest(request) return nil } func (s *server) handleRequest(request *request) { defer close(request.request) for i := 0; i < maxRequestsPerIP; i++ { conn, err := net.ListenUDP("udp", &net.UDPAddr{Port: 1080, IP: request.ip}}) if err != nil { log.Printf("Error while listening for UDP connection: %v", err) continue } request.request <- conn } } func main() { server := NewServer() listener, err := net.Listen("tcp", ":8080")) if err != nil { log.Fatal(err) } defer listener.Close() for { conn, _ := listener.Accept() go server.Serve(conn, conn.RemoteAddr())) } }