Base IRC server started.
Support for NICK, USER, QUIT, PING, and PONG commands added
This commit is contained in:
		
							parent
							
								
									89428e0e2e
								
							
						
					
					
						commit
						acfc3f2c60
					
				
							
								
								
									
										170
									
								
								client.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								client.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,170 @@
 | 
			
		||||
package irc
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/sorcix/irc"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Client represents an IRC Client connection to the server
 | 
			
		||||
type Client struct {
 | 
			
		||||
	*irc.Conn
 | 
			
		||||
	conn     net.Conn
 | 
			
		||||
	Nickname string
 | 
			
		||||
	Name     string
 | 
			
		||||
	Host     string
 | 
			
		||||
	Username string
 | 
			
		||||
	RealName string
 | 
			
		||||
 | 
			
		||||
	Prefix *irc.Prefix
 | 
			
		||||
 | 
			
		||||
	server     *Server
 | 
			
		||||
	authorized bool
 | 
			
		||||
 | 
			
		||||
	idleTimer *time.Timer
 | 
			
		||||
	quitTimer *time.Timer
 | 
			
		||||
 | 
			
		||||
	awayMessage string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Server) newClient(ircConn *irc.Conn, conn net.Conn) *Client {
 | 
			
		||||
	client := &Client{Conn: ircConn, conn: conn, server: s}
 | 
			
		||||
	client.authorized = len(s.config.Password) == 0
 | 
			
		||||
	client.idleTimer = time.AfterFunc(time.Minute, client.idle)
 | 
			
		||||
	return client
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Close cleans up the IRC client and closes the connection
 | 
			
		||||
func (c *Client) Close() error {
 | 
			
		||||
	c.server.RemoveClient(c)
 | 
			
		||||
	c.server.RemoveClientNick(c)
 | 
			
		||||
 | 
			
		||||
	return c.Conn.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Ping sends an IRC PING command to a client
 | 
			
		||||
func (c *Client) Ping() {
 | 
			
		||||
	m := irc.Message{Command: irc.PING, Params: []string{"JuddBot"}, Trailing: "JuddBot"}
 | 
			
		||||
	c.Encode(&m)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pong sends an IRC PONG command to the client
 | 
			
		||||
func (c *Client) Pong() {
 | 
			
		||||
	m := irc.Message{Command: irc.PONG, Params: []string{"JuddBot"}, Trailing: "JuddBot"}
 | 
			
		||||
	c.Encode(&m)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) handleIncoming() {
 | 
			
		||||
	c.server.AddClient(c)
 | 
			
		||||
	for {
 | 
			
		||||
		message, err := c.Decode()
 | 
			
		||||
		if err != nil || message == nil {
 | 
			
		||||
 | 
			
		||||
			_, closedError := err.(*net.OpError)
 | 
			
		||||
			if err == io.EOF || err == io.ErrClosedPipe || closedError || strings.Contains(err.Error(), "use of closed network connection") {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			println("Error decoding incoming message", err.Error())
 | 
			
		||||
			return
 | 
			
		||||
			//continue
 | 
			
		||||
		}
 | 
			
		||||
		//println(message.String())
 | 
			
		||||
 | 
			
		||||
		c.idleTimer.Stop()
 | 
			
		||||
		c.idleTimer = time.AfterFunc(time.Minute, c.idle)
 | 
			
		||||
		if c.quitTimer != nil {
 | 
			
		||||
			c.quitTimer.Stop()
 | 
			
		||||
			c.quitTimer = nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		c.server.CommandsMux.ServeIRC(message, c)
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) idle() {
 | 
			
		||||
	c.Ping()
 | 
			
		||||
	c.quitTimer = time.AfterFunc(time.Minute, c.quit)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) quit() {
 | 
			
		||||
	c.Quit()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Quit sends the IRC Quit command and closes the connection
 | 
			
		||||
func (c *Client) Quit() {
 | 
			
		||||
	m := irc.Message{Prefix: &irc.Prefix{Name: c.server.config.Name}, Command: irc.QUIT,
 | 
			
		||||
		Params: []string{c.Nickname}}
 | 
			
		||||
 | 
			
		||||
	c.Encode(&m)
 | 
			
		||||
	c.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Welcome handles initial client connection IRC protocols for a client.
 | 
			
		||||
// Welcome procedure includes IRC WELCOME, Host Info, and MOTD
 | 
			
		||||
func (c *Client) Welcome() {
 | 
			
		||||
 | 
			
		||||
	// Have all client info now
 | 
			
		||||
	c.Prefix = &irc.Prefix{Name: c.Nickname, User: c.Username, Host: c.Host}
 | 
			
		||||
 | 
			
		||||
	m := irc.Message{Prefix: c.server.Prefix, Command: irc.RPL_WELCOME,
 | 
			
		||||
		Params: []string{c.Nickname, c.server.config.Welcome}}
 | 
			
		||||
 | 
			
		||||
	err := c.Encode(&m)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m = irc.Message{Prefix: c.server.Prefix, Command: irc.RPL_YOURHOST,
 | 
			
		||||
		Params: []string{c.Nickname, fmt.Sprintf("Your host is %s", c.server.config.Name)}}
 | 
			
		||||
 | 
			
		||||
	err = c.Encode(&m)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m = irc.Message{Prefix: c.server.Prefix, Command: irc.RPL_CREATED,
 | 
			
		||||
		Params: []string{c.Nickname, fmt.Sprintf("This server was created %s", c.server.created)}}
 | 
			
		||||
 | 
			
		||||
	err = c.Encode(&m)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m = irc.Message{Prefix: c.server.Prefix, Command: irc.RPL_MYINFO,
 | 
			
		||||
		Params: []string{c.Nickname, fmt.Sprintf("%s  - Golang IRC server", c.server.config.Name)}}
 | 
			
		||||
 | 
			
		||||
	err = c.Encode(&m)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m = irc.Message{Prefix: c.server.Prefix, Command: irc.RPL_MOTDSTART,
 | 
			
		||||
		Params: []string{c.Nickname, fmt.Sprintf("%s  - Message of the day", c.server.config.Name)}}
 | 
			
		||||
 | 
			
		||||
	err = c.Encode(&m)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m = irc.Message{Prefix: c.server.Prefix, Command: irc.RPL_MOTD,
 | 
			
		||||
		Params: []string{c.Nickname, c.server.config.MOTD}}
 | 
			
		||||
 | 
			
		||||
	err = c.Encode(&m)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m = irc.Message{Prefix: c.server.Prefix, Command: irc.RPL_ENDOFMOTD,
 | 
			
		||||
		Params: []string{c.Nickname, "End of MOTD"}}
 | 
			
		||||
 | 
			
		||||
	err = c.Encode(&m)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										127
									
								
								commands.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								commands.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,127 @@
 | 
			
		||||
package irc
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"github.com/sorcix/irc"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CommandHandler allows objects implementing this interface to be registered to serve a particular IRC command
 | 
			
		||||
type CommandHandler interface {
 | 
			
		||||
	ServeIRC(message *irc.Message, client *Client)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CommandHandlerFunc is a wrapper to to use regular functions as a CommandHandler
 | 
			
		||||
type CommandHandlerFunc func(message *irc.Message, client *Client)
 | 
			
		||||
 | 
			
		||||
// ServeIRC services a given IRC message from the given client
 | 
			
		||||
func (f CommandHandlerFunc) ServeIRC(message *irc.Message, client *Client) {
 | 
			
		||||
	f(message, client)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PingHandler is a CommandHandler to respond to IRC PING commands from a client
 | 
			
		||||
// Implemented according to RFC 1459 4.6.2 and RFC 2812 3.7.2
 | 
			
		||||
func PingHandler(message *irc.Message, client *Client) {
 | 
			
		||||
	client.Pong()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PongHandler is a CommandHandler to respond to IRC PONG commands from a client
 | 
			
		||||
// Implemented according to RFC 1459 4.6.3 and RFC 2812 3.7.3
 | 
			
		||||
func PongHandler(message *irc.Message, client *Client) {
 | 
			
		||||
	//client.Ping()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// QuitHandler is a CommandHandler to respond to IRC QUIT commands from a client
 | 
			
		||||
// Implemented according to RFC 1459 4.1.6 and RFC 2812 3.1.7
 | 
			
		||||
func QuitHandler(message *irc.Message, client *Client) {
 | 
			
		||||
 | 
			
		||||
	m := irc.Message{Prefix: client.server.Prefix, Command: irc.ERROR, Trailing: "quit"}
 | 
			
		||||
 | 
			
		||||
	client.Encode(&m)
 | 
			
		||||
	client.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NickHandler is a CommandHandler to respond to IRC NICK commands from a client
 | 
			
		||||
// Implemented according to RFC 1459 4.1.2 and RFC 2812 3.1.2
 | 
			
		||||
func NickHandler(message *irc.Message, client *Client) {
 | 
			
		||||
 | 
			
		||||
	var m irc.Message
 | 
			
		||||
	name := client.server.config.Name
 | 
			
		||||
	nickname := client.Nickname
 | 
			
		||||
 | 
			
		||||
	if len(message.Params) == 0 {
 | 
			
		||||
		m = irc.Message{Prefix: &irc.Prefix{Name: name}, Command: irc.ERR_NONICKNAMEGIVEN, Trailing: "No nickname given"}
 | 
			
		||||
		client.Encode(&m)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	newNickname := message.Params[0]
 | 
			
		||||
 | 
			
		||||
	_, found := client.server.ClientsByNick[newNickname]
 | 
			
		||||
 | 
			
		||||
	switch {
 | 
			
		||||
	case !client.authorized:
 | 
			
		||||
		m = irc.Message{Prefix: &irc.Prefix{Name: name}, Command: irc.ERR_PASSWDMISMATCH, Params: []string{newNickname}, Trailing: "Password incorrect"}
 | 
			
		||||
 | 
			
		||||
	case found: // nickname already in use
 | 
			
		||||
		fmt.Println("Nickname already used")
 | 
			
		||||
		m = irc.Message{Prefix: &irc.Prefix{Name: name}, Command: irc.ERR_NICKNAMEINUSE, Params: []string{newNickname}, Trailing: "Nickname is already in use"}
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		if len(client.Nickname) == 0 && len(client.Username) != 0 { // Client is connected now, show MOTD ...
 | 
			
		||||
			client.Nickname = newNickname
 | 
			
		||||
			client.server.AddClientNick(client)
 | 
			
		||||
			client.Welcome()
 | 
			
		||||
		} else { //change client name
 | 
			
		||||
			client.Nickname = newNickname
 | 
			
		||||
			client.server.UpdateClientNick(client, nickname)
 | 
			
		||||
			//fmt.Println("Updating client name")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(m.Command) != 0 {
 | 
			
		||||
		client.Encode(&m)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UserHandler is a CommandHandler to respond to IRC USER commands from a client
 | 
			
		||||
// Implemented according to RFC 1459 4.1.3 and RFC 2812 3.1.3
 | 
			
		||||
func UserHandler(message *irc.Message, client *Client) {
 | 
			
		||||
	var m irc.Message
 | 
			
		||||
	serverName := client.server.config.Name
 | 
			
		||||
	//nickname := client.Nickname
 | 
			
		||||
 | 
			
		||||
	if len(client.Username) != 0 { // Already registered
 | 
			
		||||
		m = irc.Message{Prefix: &irc.Prefix{Name: serverName}, Command: irc.ERR_ALREADYREGISTRED, Trailing: "You may not reregister"}
 | 
			
		||||
		client.Encode(&m)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(message.Params) != 3 {
 | 
			
		||||
		m = irc.Message{Prefix: &irc.Prefix{Name: serverName}, Command: irc.ERR_NEEDMOREPARAMS, Trailing: "Not enough parameters"}
 | 
			
		||||
		client.Encode(&m)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	name := message.Params[0]
 | 
			
		||||
	username := message.Params[1]
 | 
			
		||||
	hostname := message.Params[2]
 | 
			
		||||
	realName := message.Trailing
 | 
			
		||||
 | 
			
		||||
	client.Name = name
 | 
			
		||||
	client.Username = username
 | 
			
		||||
	client.Host = hostname
 | 
			
		||||
	client.RealName = realName
 | 
			
		||||
	if len(m.Command) == 0 && len(client.Nickname) != 0 { // Client has finished connecting
 | 
			
		||||
		client.Welcome()
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(m.Command) != 0 {
 | 
			
		||||
		client.Encode(&m)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								mux.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								mux.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
package irc
 | 
			
		||||
 | 
			
		||||
import "github.com/sorcix/irc"
 | 
			
		||||
 | 
			
		||||
// CommandsMux multiplexes incoming IRC commands
 | 
			
		||||
type CommandsMux struct {
 | 
			
		||||
	commands map[string]CommandHandler
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewCommandsMux creates and returns a new CommandsMux
 | 
			
		||||
func NewCommandsMux() CommandsMux {
 | 
			
		||||
	return CommandsMux{commands: map[string]CommandHandler{}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Handle registers the given CommandHandler for a given IRC command
 | 
			
		||||
func (c *CommandsMux) Handle(command string, handler CommandHandler) {
 | 
			
		||||
	c.commands[command] = handler
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HandleFunc registers the given handler function for a given IRC command
 | 
			
		||||
func (c *CommandsMux) HandleFunc(command string, handler CommandHandlerFunc) {
 | 
			
		||||
	c.commands[command] = CommandHandler(handler)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ServeIRC dispatches the incoming IRC command to the appropriate handler
 | 
			
		||||
func (c *CommandsMux) ServeIRC(message *irc.Message, client *Client) {
 | 
			
		||||
	h, ok := c.commands[message.Command]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		m := irc.Message{Command: irc.ERR_UNKNOWNCOMMAND}
 | 
			
		||||
		client.Encode(&m)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	h.ServeIRC(message, client)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										136
									
								
								server.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								server.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,136 @@
 | 
			
		||||
package irc
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/sorcix/irc"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Server represents an IRC server
 | 
			
		||||
type Server struct {
 | 
			
		||||
	config ServerConfig
 | 
			
		||||
 | 
			
		||||
	Clients     map[net.Addr]*Client
 | 
			
		||||
	clientMutex sync.RWMutex
 | 
			
		||||
 | 
			
		||||
	ClientsByNick     map[string]*Client
 | 
			
		||||
	clientByNickMutex sync.RWMutex
 | 
			
		||||
 | 
			
		||||
	Prefix      *irc.Prefix
 | 
			
		||||
	CommandsMux CommandsMux
 | 
			
		||||
	created     time.Time
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ServerConfig contains configuration data for seeding a server
 | 
			
		||||
type ServerConfig struct {
 | 
			
		||||
	Name      string
 | 
			
		||||
	MOTD      string
 | 
			
		||||
	Welcome   string
 | 
			
		||||
	TLSConfig *tls.Config
 | 
			
		||||
	Addr      string
 | 
			
		||||
 | 
			
		||||
	Password string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewServer creates and returns a new Server based on the provided config
 | 
			
		||||
func NewServer(config ServerConfig) *Server {
 | 
			
		||||
	s := Server{}
 | 
			
		||||
	s.config = config
 | 
			
		||||
	s.Clients = map[net.Addr]*Client{}
 | 
			
		||||
	s.CommandsMux = NewCommandsMux()
 | 
			
		||||
	s.created = time.Now()
 | 
			
		||||
	s.ClientsByNick = map[string]*Client{}
 | 
			
		||||
	s.Prefix = &irc.Prefix{Name: config.Name}
 | 
			
		||||
 | 
			
		||||
	return &s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddClient adds a new Client
 | 
			
		||||
func (s *Server) AddClient(client *Client) {
 | 
			
		||||
	s.clientMutex.Lock()
 | 
			
		||||
	defer s.clientMutex.Unlock()
 | 
			
		||||
	s.Clients[client.conn.RemoteAddr()] = client
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RemoveClient removes a client
 | 
			
		||||
func (s *Server) RemoveClient(client *Client) {
 | 
			
		||||
	s.clientMutex.Lock()
 | 
			
		||||
	defer s.clientMutex.Unlock()
 | 
			
		||||
	delete(s.Clients, client.conn.RemoteAddr())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetClient finds a client by its address and returns it
 | 
			
		||||
func (s *Server) GetClient(addr net.Addr) *Client {
 | 
			
		||||
	s.clientMutex.RLock()
 | 
			
		||||
	defer s.clientMutex.RUnlock()
 | 
			
		||||
	return s.Clients[addr]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddClientNick adds a client based on its nickname
 | 
			
		||||
func (s *Server) AddClientNick(client *Client) {
 | 
			
		||||
	s.clientByNickMutex.Lock()
 | 
			
		||||
	defer s.clientByNickMutex.Unlock()
 | 
			
		||||
	s.ClientsByNick[client.Nickname] = client
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RemoveClientNick removes a client based on its nickname
 | 
			
		||||
func (s *Server) RemoveClientNick(client *Client) {
 | 
			
		||||
	s.clientByNickMutex.Lock()
 | 
			
		||||
	defer s.clientByNickMutex.Unlock()
 | 
			
		||||
	delete(s.ClientsByNick, client.Nickname)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UpdateClientNick updates the nickname of a client as it is stored by the server
 | 
			
		||||
func (s *Server) UpdateClientNick(client *Client, oldNick string) {
 | 
			
		||||
	s.clientByNickMutex.Lock()
 | 
			
		||||
	defer s.clientByNickMutex.Unlock()
 | 
			
		||||
	delete(s.ClientsByNick, oldNick)
 | 
			
		||||
	s.ClientsByNick[client.Nickname] = client
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetClientByNick returns a client with the corresponding nickname
 | 
			
		||||
func (s *Server) GetClientByNick(nick string) *Client {
 | 
			
		||||
	s.clientByNickMutex.RLock()
 | 
			
		||||
	defer s.clientByNickMutex.RUnlock()
 | 
			
		||||
	return s.ClientsByNick[nick]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Start the server listening on the configured port
 | 
			
		||||
func (s *Server) Start() {
 | 
			
		||||
	var listener net.Listener
 | 
			
		||||
	var err error
 | 
			
		||||
	if s.config.TLSConfig != nil {
 | 
			
		||||
		listener, err = tls.Listen("tcp", s.config.Addr, s.config.TLSConfig)
 | 
			
		||||
	} else {
 | 
			
		||||
		listener, err = net.Listen("tcp", s.config.Addr)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		fmt.Println("Error starting listner", err.Error())
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		conn, err := listener.Accept()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Println("Error accepting connection", err.Error())
 | 
			
		||||
			//return
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ircConn := irc.NewConn(conn)
 | 
			
		||||
		client := s.newClient(ircConn, conn)
 | 
			
		||||
 | 
			
		||||
		defer client.Close()
 | 
			
		||||
		go func() {
 | 
			
		||||
			fmt.Println("Incoming connection from:", conn.RemoteAddr())
 | 
			
		||||
			client.handleIncoming()
 | 
			
		||||
			fmt.Println("Disconnected with:", conn.RemoteAddr())
 | 
			
		||||
		}()
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user