require File.dirname(__FILE__) + '/../config/environment.rb' require 'socket' require 'thread' require 'nntp' require 'log4r' #include Log4r PORT = 9999 MAX_CONNS_PER_IP = 3 MAX_CONNS = 30 logger = Log4r::Logger.new "nntpd" logger.outputters = Log4r::Outputter.stdout Thread.abort_on_exception = true server = TCPserver.open(PORT) logger.info "Listening on #{PORT}" conns_counter_mutex = Mutex.new conns = 0 conns_per_ip = Hash.new loop do socket = server.accept ip = socket.peeraddr[3] logger.info "connection from #{ip}" if conns >= MAX_CONNS logger.info "too many connections" socket.warn "502 Too many connections\r\n" socket.shutdown next end if conns_per_ip[ip].to_i >= MAX_CONNS_PER_IP logger.warn "too many connections from #{ip}" socket.write "502 Too many connections from #{ip}\r\n" socket.shutdown next end conns_counter_mutex.synchronize do conns += 1 if conns_per_ip[ip] == nil conns_per_ip[ip] = 1 else conns_per_ip[ip] += 1 end end Thread.start(socket, ip, logger) do |socket, ip, logger| begin NNTPSession.new(socket, logger).serve rescue => err logger.error err ensure socket.shutdown rescue nil GC.start conns_counter_mutex.synchronize do conns -= 1 conns_per_ip[ip] -= 1 end logger.info "connection to #{ip} lost" end end end