Skip to content

Instantly share code, notes, and snippets.

@rafkatg
Created February 24, 2024 13:56
Show Gist options
  • Save rafkatg/c8b5d233d003fae9c17aa0a4a6df92d9 to your computer and use it in GitHub Desktop.
Save rafkatg/c8b5d233d003fae9c17aa0a4a6df92d9 to your computer and use it in GitHub Desktop.
GOGOGO
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()))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment