dircd

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 20, 2020 License: BSD-3-Clause Imports: 13 Imported by: 0

README

dircd

A derpy IRCd written in Go.

Why?

Because I wanted to.

Status

Heavy Development.

Can connect, can PRIVMSG, join/talk on channels. Connections are -fairly- resilient. I modeled the connection handling code after Golang stdlib http server, and just trimmed out the HTTP protocol handling and shoved in IRC protocol handling. Trying to model it after the ease of use of Golang stdlib HTTP server and have a mostly clean API. I wanted to do it right cause I had plans to make a bigger project out of it.

Currently iterating on modes/permissions before I start fleshing out more of the features that heavily rely on them.

Need to do better with ISUPPORT, but for the most part the static configuration it currently has is RFC compliant, even if some of the stuff it says is a lie.

Some stuff to do (not exhaustive):

  • Modes
    • User Modes
    • Channel Modes
    • Setting
    • Parameter Lists
    • Mode effect logic
  • Nickname rule enforcement
  • CAP negotiation
    • message-tag
    • SASL
    • more when I decide what I want to include
  • Persistance
  • Message Filtering
  • Authentication
  • Multiple Server architecture design?

Contribute?

Send pull requests, submit issues, whatever.

Licsense

3-Clause BSD (At the top of each source file).

Documentation

Index

Constants

View Source
const (
	SaslPlain uint8 = iota
	SaslLogin
	SaslExternal
	SaslGSSAPI
	SaslCramMD5
	SaslDigestMD5
	SaslScramSHA1
)

SASL Types

View Source
const (
	// RFC 1459
	CmdPrivMsg  string = "PRIVMSG"
	CmdNotice          = "NOTICE"
	CmdUserhost        = "USERHOST"
	CmdPass            = "PASS"
	CmdPing            = "PING"
	CmdPong            = "PONG"
	CmdTopic           = "TOPIC"
	CmdJoin            = "JOIN"
	CmdPart            = "PART"
	CmdKick            = "KICK"
	CmdQuit            = "QUIT"
	CmdNick            = "NICK"
	CmdUser            = "USER"
	CmdMode            = "MODE"
	CmdWallops         = "WALLOPS"
	CmdInvite          = "INVITE"
	CmdKill            = "KILL"

	// CTCP
	CmdCTCPPing       = "CTCP PING"
	CmdCTCPVersion    = "CTCP VERSION"
	CmdCTCPSource     = "CTCP SOURCE"
	CmdCTCPTime       = "CTCP TIME"
	CmdCTCPUserInfo   = "CTCP USERINFO"
	CmdCTCPClientInfo = "CTCP CLIENTINFO"
	CmdCTCPError      = "CTCP ERRMSG"
	CmdCTCPFinger     = "CTCP FINGER"
	CmdCTCPAction     = "CTCP ACTION"

	// IRCv3.1 Base
	CmdCap     = "CAP"
	CmdCapLs   = "CAP LS"
	CmdCapList = "CAP LIST"
	CmdCapReq  = "CAP REQ"
	CmdCapAck  = "CAP ACK"
	CmdCapNak  = "CAP NAK"
	CmdCapEnd  = "CAP END"
	CmdAuth    = "AUTHENTICATE"

	// IRCv3.1 account-notify
	CmdAccount = "ACCOUNT"

	// IRCv3.1 away-notify
	CmdAway = "AWAY"

	// IRCv3.2 Base
	CmdMetadata = "METADATA"
)

Command constants.

View Source
const (
	SPACE  string = " "
	CRLF          = "\r\n"
	COLON         = ":"
	EMPTY         = ""
	PADNUM        = "%03d"
)

String constants for constructing the message

View Source
const (
	ReplyNone                uint16 = 000
	ReplyWelcome                    = 001
	ReplyYourHost                   = 002
	ReplyCreated                    = 003
	ReplyMyInfo                     = 004
	ReplyISupport                   = 005
	ReplyBounce                     = 010
	ReplyNickForceChanged           = 043
	ReplyTraceLink                  = 200
	ReplyTraceConnecting            = 201
	ReplyTraceHandshake             = 202
	ReplyTraceUnknown               = 203
	ReplyTraceOperator              = 204
	ReplyTraceUser                  = 205
	ReplyTraceServer                = 206
	ReplyTraceService               = 207
	ReplyTraceNewType               = 208
	ReplyTraceClass                 = 209
	ReplyStats                      = 210
	ReplyStatsLinkInfo              = 211
	ReplyStatsCommands              = 212
	ReplyStatsCLine                 = 213
	ReplyStatsNLine                 = 214
	ReplyStatsILine                 = 215
	ReplyStatsKLine                 = 216
	ReplyStatsQLine                 = 217
	ReplyStatsYLine                 = 218
	ReplyEndOfStats                 = 219
	ReplyUserModeIs                 = 221
	ReplyServiceInfo                = 231
	ReplyEndOfServices              = 232
	ReplyServerList                 = 234
	ReplyEndOfServerList            = 235
	ReplyStatsUptime                = 242
	ReplyStatsNetOp                 = 243
	ReplyStatsHelpOp                = 244
	ReplyStatsPing                  = 246
	ReplyUsersOnlineGlobal          = 251
	ReplyOpersOnline                = 252
	ReplyUnknownConnections         = 253
	ReplyChannelCount               = 254
	ReplyUsersOnlineLocal           = 255
	ReplyAdminInfoStart             = 256
	ReplyAdminInfo1                 = 257
	ReplyAdminInfo2                 = 258
	ReplyAdminEmail                 = 259
	ReplyTraceLog                   = 261
	ReplyEndOfTrace                 = 262
	ReplyTryAgain                   = 263
	ReplyAway                       = 301
	ReplyUserHost                   = 302
	ReplyIsOn                       = 303
	ReplyUnAway                     = 305
	ReplyNowAway                    = 306
	ReplyWhoisUser                  = 311
	ReplyWhoisServer                = 312
	ReplyWhoisOperator              = 313
	ReplyWhoWasUser                 = 314
	ReplyEndOfWho                   = 315
	ReplyWhoisChanOp                = 316
	ReplyWhoisIdle                  = 317
	ReplyEndOfWhois                 = 318
	ReplyWhoisChannels              = 319
	ReplyListStart                  = 321
	ReplyList                       = 322
	ReplyEndOfList                  = 323
	ReplyChannelModeIs              = 324
	ReplyNoTopic                    = 331
	ReplyChanTopic                  = 332
	ReplyInviting                   = 341
	ReplyInvited                    = 345
	ReplyInviteList                 = 346
	ReplyEndOfInviteList            = 347
	ReplyExceptList                 = 348
	ReplyEndOfExceptList            = 349
	ReplyVersion                    = 351
	ReplyWho                        = 352
	ReplyNames                      = 353
	ReplyLinks                      = 384
	ReplyEndOfLinks                 = 365
	ReplyEndOfNames                 = 366
	ReplyBanList                    = 367
	ReplyEndOfBanList               = 368
	ReplyEndOfWhoWas                = 369
	ReplyInfo                       = 371
	ReplyMOTD                       = 372
	ReplyEndOfInfo                  = 374
	ReplyMOTDStart                  = 375
	ReplyEndOFMOTD                  = 376
	ReplyYoureOper                  = 381
	ReplyRehashing                  = 382
	ReplyYoureService               = 383
	ReplyTime                       = 391
	ReplyUsersStart                 = 392
	ReplyUsers                      = 393
	ReplyEndOfUsers                 = 394
	ReplyNoUsers                    = 395
	ReplyNoSuchNick                 = 401
	ReplyNoSuchServer               = 402
	ReplyNoSuchChannel              = 403
	ReplyCannotSendToChan           = 404
	ReplyTooManyChannels            = 405
	ReplyWasNoSuchNick              = 406
	ReplyTooManyTargets             = 407
	ReplyNoSuchService              = 408
	ReplyNoOrigin                   = 409
	ReplyInvalidCapCmd              = 410
	ReplyNoRecipient                = 411
	ReplyNoTextToSend               = 412
	ReplyNoTopLevel                 = 413
	ReplyWildTopLevel               = 414
	ReplyBadMask                    = 415
	ReplyTooManyMatches             = 416
	ReplyUnknownCommand             = 421
	ReplyNoMOTD                     = 422
	ReplyNoAdminInfo                = 423
	ReplyFileError                  = 424
	ReplyNoNicknameGiven            = 431
	ReplyErroneusNickname           = 432
	ReplyNicknameInUse              = 433
	ReplyNickCollision              = 436
	ReplyResourceUnavailable        = 437
	ReplyUserNotInChannel           = 441
	ReplyNotOnChannel               = 442
	ReplyUserOnChannel              = 443
	ReplyNoLogin                    = 447
	ReplySummonDisabled             = 446
	ReplyUsersDisabled              = 446
	ReplyNotRegistered              = 451
	ReplyNeedMoreParams             = 461
	ReplyAlreadyRegistered          = 462
	ReplyNoPermForHost              = 463
	ReplyPasswordMistmatch          = 464
	ReplyYoureBanned                = 465
	ReplyYouWillBeBanned            = 466
	ReplyChanPassAlreadySet         = 467
	ReplyChannelIsFull              = 471
	ReplyUnknownMode                = 472
	ReplyInviteOnlyChan             = 473
	ReplyBannedFromChan             = 474
	ReplyBadChannelPass             = 475
	ReplyBadChannelName             = 476
	ReplyNoChanModes                = 477
	ReplyBanListFUll                = 478
	ReplyNoPrivileges               = 481
	ReplyChanOpPrivsNeeded          = 482
	ReplyCantKillServer             = 483
	ReplyRestricted                 = 484
	ReplyChanOwnerRequired          = 485
	ReplyNoOperHost                 = 491
	ReplyNoServiceHost              = 492
	ReplyUnknownUserMode            = 501
	ReplyUsersDontMatch             = 502
	ReplyLoggedIn                   = 900
	ReplyLoggedOut                  = 901
	ReplySASLSuccess                = 903
	ReplySASLFail                   = 904
	ReplySASLTooLong                = 905
	ReplySASLAborted                = 906
	ReplySASLAlready                = 907
)

RFC 2812/1459 numerics

View Source
const (
	UPermBan uint8 = iota
	UPermNone
	UPermUser
	UPermHelpOp
	UPermNetOp
	UPermAdmin
	UPermServer
)

User permission levels on the server.

View Source
const (
	// Messages
	MaxMsgLength int = 512
	MaxMsgParams     = 15

	// Channels
	MaxChanLength  = 16
	MaxKickLength  = 400
	MaxTopicLength = 400
	MaxListItems   = 256
	MaxModeChange  = 6

	// Users
	MaxNickLength  = 16
	MaxUserLength  = 16
	MaxVHostLength = 64
	MaxJoinedChans = 32
	MaxAwayLength  = 100
)

Limiter Constants

View Source
const (
	UModeAway uint64 = 1 << iota
	UModeAdmin
	UModeBot
	UModeBanned
	UModeCensored
	UModeConnInfo
	UModeDeaf
	UModeDebug
	UModeFloodInfo
	UModeFloodImmune
	UModeGodmode
	UModeHiddenHost
	UModeHidden
	UModeInvisible
	UModeImmune
	UModeKeyMaster
	UModeMuted
	UModeHelpOp
	UModeNetOp
	UModeProtected
	UModeRegistered
	UModeSecured
	UModeThrottled
	UModeGlobalVoice
	UModeWhoisInfo
	UModeWatch
)

Usermode Bitmasks

View Source
const BufferPoolMax = 1000

BufferPoolMax sets the bytes.Buffer pool length

View Source
const KeepAliveTimeout time.Duration = 2 * time.Minute

KeepAliveTimeout sets the connection timeout duration on the client IRC connections.

View Source
const MessagePoolMax = 1000

MessagePoolMax sets the message pool buffer length

View Source
const PingTimeout time.Duration = 30 * time.Second

PingTimeout sets the PING/PONG timeout duration on the client IRC connections.

View Source
const WriteQueueLength = 10

WriteQueueLength sets the length of each connections write queue channel.

View Source
const WriteTimeout time.Duration = 5 * time.Second

WriteTimeout sets the write timeout duration on the client IRC connections.

Variables

View Source
var Handlers = make(map[string]MessageHandler)

Handlers is a map of functions where the handlers are stored.

UModeReqs is a map of usermodes with required setter/target permissions levels defined.

Functions

func HandleCap

func HandleCap(conn *Conn, msg *Message)

HandleCap processes the CAP command and sub commands for negotiating capabilties per the IRCv3.2 spec.

Command: CAP
Parameters: <subcommand> [param] :[capabiliy] [capability]

func HandleJoin

func HandleJoin(conn *Conn, msg *Message)

HandleJoin processes a JOIN command.

The server will first check if the channel exists, if not, create a new channel. Then, the user will be added to the channel members if the the user has sufficient permissions; which are implied if the channel must first be created.

Command: JOIN
Prameters: <channel>

func HandleNick

func HandleNick(conn *Conn, msg *Message)

HandleNick processes a NICK command.

First, it checks if the current nickname is in use by the user issuing the command; by another user on the server; or disallowed by the server configuration. Then it checks the validity of the nickname formatting before finally, if all of the requirements are met, sets the User object Nick field to the specified name in the command parameters.

Command: NICK
Parameters: <nickname>

func HandleNotice

func HandleNotice(conn *Conn, msg *Message)

HandleNotice processes a NOTICE command.

First, it checks if the specified nickname or channel exists; then checks if the sender is disallowed from sending the message by the sender's usermode. If all of the requirements are met, it sends the message to the intended recpient.

Command: NOTICE
Parameters: <target> :<text>

func HandlePing

func HandlePing(conn *Conn, msg *Message)

HandlePing processes a PING command originated from the client.

The server will respond with the matching ping token.

Command: PING
Parameters: :<token>

func HandlePong

func HandlePong(conn *Conn, msg *Message)

HandlePong processes a PONG command in reply to a server sent PING command.

Command: PONG Parameters: :<token>

func HandlePrivmsg

func HandlePrivmsg(conn *Conn, msg *Message)

HandlePrivmsg processes a PRIVMSG command.

First, it checks if the specified nickname or channel exists; then checks if the sender is disallowed from sending the message by the sender's usermode. If all of the requirements are met, it sends the message to the intended recpient.

Command: PRIVMSG
Parameters: <target> :<text>

func HandleQuit

func HandleQuit(conn *Conn, msg *Message)

HandleQuit processes a QUIT command.

The connection will be scheduled for immediate deadline, and the server will broadcast the QUIT message to all channels the user is joined to.

Command: QUIT
Parameters: :<reason>

func HandleUser

func HandleUser(conn *Conn, msg *Message)

HandleUser processes a USER command.

First, it checks if the specieifed username is in use by the user issuing the command; by another user on the server; or disallowed by the server configuration. Then it checks the validity of the username formatting before finally, if all of the requirements are met, sets the User object Name field to the specified name in the command parameters.

Command: USER
Parameters: <username> <modemask> -0(unused)- :[realname]

func HandleUserhost

func HandleUserhost(conn *Conn, msg *Message)

HandleUserhost processes a USERHOST command originated from the client.

The server will respond with the matching hostname of the requested nicks. Limit 5

Command: USERHOST
Parameters: <nickname1> [nickname2] [nickname3] [nickname4] [nickname5]

func RouteCommand

func RouteCommand(conn *Conn, msg *Message)

RouteCommand accepts an IRC message and routes it to a function in which is designed to process the command.

func SetUserMode

func SetUserMode(umode uint64, setter, target *User) error

SetUserMode is used to set a mode on a target user.

This function will lock both setter and target user mutexes.

First it determines if a user mode is valid. If this is not the case, this function will return ErrUnknownMode

Then it will then determine if the permission level of the setting user is higher than the target user, as well as if the target user's permission level is defined as being allowed to receive the specified usermode. If both are true then the mode will be set. Otherwise, this function will return ErrInsuffPerms

If the mode is already present on the user, then this function will return ErrModeAlreadySet

func UnsetUserMode

func UnsetUserMode(umode uint64, setter, target *User) error

UnsetUserMode is used to unset a mode on a target user.

This function will lock both setter and target user mutexes.

First it determines if a user mode is valid. If this is not the case, this function will return ErrUnknownMode

Then it will then determine if the permission level of the setting user is higher than the target user. If this is true, then the mode will be set. Otherwise, this function will return ErrInsuffPerms

If the mode is not already present on the user, then this function will return ErrModeNotSet

func Warmup

func Warmup(logger *logrus.Logger)

Warmup initializes the irc library for use.

Types

type Capabilities

type Capabilities struct {
	AccountNotify   bool // Notifies clients when other clients in comon channels authenticate or deauthenticate (eg: NickServ, SASL).
	AccountTag      bool // Attach a tag containing the user's account to every message they send.
	AwayNotify      bool // Notifies clients when other clients in common channels go away or come back.
	Batch           bool // Allow server to bundle common messages together.
	CapNotify       bool // Notify when capabilties become available or are no longer available.
	ChgHost         bool // Enable CHGHOST message, which lets servers notify clients when another cleint's username and/or hostname changes.
	EchoMessage     bool // Notifies clients when their PRIVMSG and NOTICEs are correctly received by the server.
	ExtendedJoin    bool // Extends the JOIN message to include the account name of the joining client.
	InviteNotify    bool // Notifies clients when other clients are invited to common channels.
	LabeledResponse bool // Allows clients to correlate requests with server responses.
	MessageTags     bool // Allows Clients and servers to use tags more broadly.
	Metadata        bool // Lets clients store metadata about themselves with the server, for other clients to request and retrieve later.
	Monitor         bool // Lets users request notifications for qhen clients become online/offline.
	MultiPrefix     bool // Makes the server send all prefixes in NAMES and WHO output, in order of rank from highest to lowest.
	Multiline       bool // Allows clients and servers to use send messages that can exceed the usual byte length limit and that can contain line breaks.
	SASL            bool // Indicates support for SASL authentication.
	ServerTime      bool // Lets clients show the actual time messages were received by the server.
	Setname         bool // Lets clients change their realname after connecting to the server.
	TLS             bool // Indicates support for the STARTTLS command, which lets clients upgrade their connection to use TLS encryption.
	UserhostInNames bool // Extends the NAMEREPLY message to contain the full nickmask (nick!user@host) of every user, rather than just the nickname.
}

Capabilities contains the information for CAP negotiation.

type ChanMap

type ChanMap struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

ChanMap is a simple map[string]*Channel wrapped with a concurrent-safe API

func NewChanMap

func NewChanMap() *ChanMap

NewChanMap initializes and returns a pointer to a new ChanMap instance.

func (*ChanMap) Add

func (m *ChanMap) Add(key string, value *Channel) error

Add is used to add a key/value to the map. Returns an error if the key already exists.

func (*ChanMap) Del

func (m *ChanMap) Del(key string) error

Del is used to remove a key/value from the map. Returns an error if the key does not exist.

func (*ChanMap) Exists

func (m *ChanMap) Exists(key string) bool

Exists is used by external callers to check if a value exists in the map and returns a boolean with the result.

func (*ChanMap) ForEach

func (m *ChanMap) ForEach(do func(*Channel))

ForEach will call the provided function for each entry in the ChanMap

func (*ChanMap) Get

func (m *ChanMap) Get(key string) (*Channel, error)

Get is used to get a key/value from the map. Returns an error if the key does not exist.

func (*ChanMap) Length

func (m *ChanMap) Length() int

Length returns the length of the underlying map.

func (*ChanMap) Set

func (m *ChanMap) Set(key string, value *Channel) error

Set is used to change an existing key/value in the map. Returns an error if the key does not exist.

type Channel

type Channel struct {
	sync.RWMutex

	// Active Lists
	Nicks   *UserMap
	Ops     *UserMap
	HalfOps *UserMap
	Voiced  *UserMap

	// Persisted Lists
	// map[hostpattern]setter
	OpList     *util.ConcurrentMapString
	HalfOpList *util.ConcurrentMapString
	VoiceList  *util.ConcurrentMapString
	BanList    *util.ConcurrentMapString
	InviteList *util.ConcurrentMapString
	// contains filtered or unexported fields
}

Channel represents an IRC channel

func NewChannel

func NewChannel(cname string, creator *User) *Channel

NewChannel initializes a Channel with the given name and owner.

func (*Channel) GetNicks

func (channel *Channel) GetNicks() []string

GetNicks returns an array of the current nicknames of the users in the chanel.

func (*Channel) Join

func (channel *Channel) Join(user *User, msg *Message) bool

Join adds the user to the channel and alerts all channel members of the event.

func (*Channel) Name

func (channel *Channel) Name() string

Name returns the name of the channel in a currency safe manner.

func (*Channel) Owner

func (channel *Channel) Owner() *User

Owner returns the owner of the channel in a currency safe manner.

func (*Channel) Part

func (channel *Channel) Part(user *User, msg *Message)

Part removes the user from the channel and alerts all channel members of the event.

func (*Channel) Send

func (channel *Channel) Send(msg *Message, exclude string)

Send takes a message, then iterates the list of Users joined to the channel stored in the Nicks map, and sends the message to each of the User's underlying connection.

func (*Channel) SetName

func (channel *Channel) SetName(new string)

SetName sets the name of the channel in a currency safe manner.

func (*Channel) SetOwner

func (channel *Channel) SetOwner(new *User)

SetOwner sets the owner of the channel in a currency safe manner.

func (*Channel) SetTopic

func (channel *Channel) SetTopic(new string)

SetTopic sets the topic of the channel in a currency safe manner.

func (*Channel) Topic

func (channel *Channel) Topic() string

Topic returns the topic of the channel in a currency safe manner.

type Conn

type Conn struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

Conn represents the server side of an IRC connection.

func NewConn

func NewConn(srv *Server, sck net.Conn) *Conn

NewConn initializes a new instance of Conn

func (*Conn) ReplyChannelNames

func (conn *Conn) ReplyChannelNames(channel *Channel)

ReplyChannelNames returns the topic reply to the user for the given channel.

func (*Conn) ReplyChannelTopic

func (conn *Conn) ReplyChannelTopic(channel *Channel)

ReplyChannelTopic returns the topic reply to the user for the given channel.

func (*Conn) ReplyISupport

func (conn *Conn) ReplyISupport()

ReplyISupport returns the topic reply to the user for the given channel.

func (*Conn) ReplyInvalidCapCommand

func (conn *Conn) ReplyInvalidCapCommand(cmd string)

ReplyInvalidCapCommand returns an error message to the user in the event that a CAP command issued by the user is not a valid subcommand per the IRCv3 CAP specifications.

func (*Conn) ReplyNeedMoreParams

func (conn *Conn) ReplyNeedMoreParams(cmd string)

ReplyNeedMoreParams returns an error message to the user in the event that a command issued by the user that does not satisfy the minimum number of parameters expected of the particualar command.

func (*Conn) ReplyNoNicknameGiven

func (conn *Conn) ReplyNoNicknameGiven()

ReplyNoNicknameGiven returns an error message to the user in the event that a command issued by the user that does not satisfy the requirement of specifying a nickname.

func (*Conn) ReplyNoSuchChan

func (conn *Conn) ReplyNoSuchChan(channel string)

ReplyNoSuchChan returns an error message to the user in the event that a command issued by the user with a target channel cannot find the target or is unable to know of the targets existence due to permissions.

func (*Conn) ReplyNoSuchNick

func (conn *Conn) ReplyNoSuchNick(nick string)

ReplyNoSuchNick returns an error message to the user in the event that a command issued by the user with a target nickname cannot find the target or is unable to know of the targets existence due to permissions.

func (*Conn) ReplyNotImplemented

func (conn *Conn) ReplyNotImplemented(cmd string)

ReplyNotImplemented returns an error message to the user in the event the given command is not apart of the handlers found in RouteCommand()

func (*Conn) ReplyNotRegistered

func (conn *Conn) ReplyNotRegistered()

ReplyNotRegistered returns an error message to the user in the event the given command is not apart of the handlers found in RouteCommand()

func (*Conn) ReplyWelcome

func (conn *Conn) ReplyWelcome()

ReplyWelcome returns the configured welcome message to the user. This is sent when a client first connects and registers successfully.

func (*Conn) Write

func (conn *Conn) Write(buffer *bytes.Buffer)

type ConnMap

type ConnMap struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

ConnMap is a simple map[string]*Conn wrapped with a concurrent-safe API

func NewConnMap

func NewConnMap() *ConnMap

NewConnMap initializes and returns a pointer to a new COnnMap instance.

func (*ConnMap) Add

func (m *ConnMap) Add(key string, value *Conn) error

Add is used to add a key/value to the map. Returns an error if the key already exists.

func (*ConnMap) Del

func (m *ConnMap) Del(key string) error

Del is used to remove a key/value from the map. Returns an error if the key does not exist.

func (*ConnMap) Exists

func (m *ConnMap) Exists(key string) bool

Exists is used by external callers to check if a value exists in the map and returns a boolean with the result.

func (*ConnMap) ForEach

func (m *ConnMap) ForEach(do func(*Conn))

ForEach will call the provided function for each entry in the UserMap

func (*ConnMap) Get

func (m *ConnMap) Get(key string) (*Conn, error)

Get is used to get a key/value from the map. Returns an error if the key does not exist.

func (*ConnMap) Length

func (m *ConnMap) Length() int

Length returns the length of the underlying map.

func (*ConnMap) Set

func (m *ConnMap) Set(key string, value *Conn) error

Set is used to change an existing key/value in the map. Returns an error if the key does not exist.

type Error

type Error string

Error is a workaround to allow for immutable error strings which satisfy the error interface.

const (
	ErrNotEnoughData  Error = "Did not receive enough data from the client"
	ErrDataTooLong    Error = "Received data from the client is too long"
	ErrCRLF           Error = "No CRLF"
	ErrWhitespace     Error = "All Whitepace"
	ErrPrefixed       Error = "Prefixed message from client"
	ErrInvalidCapCmd  Error = "Invalid CAP command"
	ErrMissingParams  Error = "Missing parameters"
	ErrTooManyParams  Error = "Too many parameters"
	ErrUserInUse      Error = "This username is currently in use"
	ErrUserRestricted Error = "This username is restricted"
	ErrUserAreadySet  Error = "You have already registered"
	ErrNickInUse      Error = "This nickname is currently in use"
	ErrNickRestricted Error = "This nickname is restricted"
	ErrNickAlreadySet Error = "You already have that nickname"
	ErrNotImplemented Error = "That command is not yet implemented"
	ErrNotRegistered  Error = "You must register first"
	ErrNoNickGiven    Error = "No nickname given"
	ErrNoSuchNick     Error = "Nick not found"
	ErrNoSuchChan     Error = "Channel not found"
	ErrInsuffPerms    Error = "Insufficient permissions"
	ErrUnknownMode    Error = "Unknown mode"
	ErrModeAlreadySet Error = "Mode already set"
	ErrModeNotSet     Error = "Mode is not set"
)

Immutable error strings

func (Error) Error

func (err Error) Error() string

func (Error) String

func (err Error) String() string

type Message

type Message struct {
	Text    string   // The portion of the message after the prefix and command.
	Sender  string   // The sender parameter of the message.
	Params  []string // The person of the message after prefix and command in array form.
	Command string   // The IRC string command of the message.
	Code    uint16   // The IRC numeric code of the message.
}

Message is an object that represents the components of an IRC message.

func Parse

func Parse(data string) (*Message, error)

Parse takes IRC-formatted text into a message object. Will return an error if the message doesn't fit the protocol.

func (*Message) Debug

func (msg *Message) Debug() string

Debug prints a message object to a string with verbose information about the object fields.

func (*Message) Render

func (msg *Message) Render() string

Render returns the IRC-formatted string version of a message object. Will return an error if there is something wrong with the meesage.

func (*Message) RenderBuffer

func (msg *Message) RenderBuffer() *bytes.Buffer

RenderBuffer returns the IRC-formatted byte buffer version of a message object. Will return an error if there is something wrong with the meesage.

func (*Message) String

func (msg *Message) String() string

String returns the IRC-formatted string version of a message object. This is here to satisfy a Stringer interface

type MessageHandler

type MessageHandler func(*Conn, *Message)

MessageHandler defines the function signature of a handler used to process IRC messages.

type MessagePool

type MessagePool struct {
	Messages chan *Message
}

MessagePool holds the Message objects in a channel as a queue.

func NewMessagePool

func NewMessagePool(max int) *MessagePool

NewMessagePool creates a new pool of Messages.

func (*MessagePool) New

func (pool *MessagePool) New() (msg *Message)

New takes a Message from the pool.

func (*MessagePool) Recycle

func (pool *MessagePool) Recycle(msg *Message)

Recycle returns a Message to the pool.

func (*MessagePool) Warmup

func (pool *MessagePool) Warmup(num int)

Warmup fills the MessagePool with the specified number of objects up to one below the maximum capacity of the internal channel

type Server

type Server struct {
	sync.RWMutex

	// Active State
	Users     *UserMap
	Nicks     *UserMap
	Conns     *ConnMap
	Channels  *ChanMap
	TLSConfig *tls.Config
	// contains filtered or unexported fields
}

Server holds the state of an IRC server instance.

func NewServer

func NewServer() *Server

NewServer initializes and returns a new instance of a Server.

func (*Server) Address

func (server *Server) Address() string

Address returns the configured address of the server in a concurrency safe manner.

func (*Server) Hostname

func (server *Server) Hostname() string

Hostname returns the configured hostname of the server in a concurrency safe manner.

func (*Server) ISupport

func (server *Server) ISupport() []string

ISupport returns a slice of formatted ISupport key=value pairs.

func (*Server) ListenAndServe

func (server *Server) ListenAndServe() error

ListenAndServe listens on the TCP network address srv.ListenAddr and then calls Serve to handle the irc.Conn sessions. Accepted connections are configured to enable TCP keep-alives.

If srv.ListenAddr is blank, ":6667" is used.

ListenAndServe always returns a non-nil error.

func (*Server) ListenAndServeTLS

func (server *Server) ListenAndServeTLS(certFile, keyFile string) error

ListenAndServeTLS listens on the TCP network address srv.Addr and then calls Serve to handle the irc.Conn sessions on a TLS connection. Accepted connections are configured to enable TCP keep-alives.

Filenames containing a certificate and matching private key for the server must be provided if neither the Server's TLSConfig.Certificates nor TLSConfig.GetCertificate are populated. If the certificate is signed by a certificate authority, the certFile should be the concatenation of the server's certificate, any intermediates, and the CA's certificate.

If srv.ListenAddr is blank, ":6697" is used.

ListenAndServeTLS always returns a non-nil error.

func (*Server) MOTD

func (server *Server) MOTD() string

MOTD returns the configured MOTD of the server in a concurrency safe manner.

func (*Server) Network

func (server *Server) Network() string

Network returns the configured network name of the server in a concurrency safe manner.

func (*Server) Serve

func (server *Server) Serve(listen net.Listener) error

Serve starts an IRC server which listens for connections on the given net.Listener, accepts them when they arrive, then assigns them to a new instance of irc.Conn

func (*Server) SetAddress

func (server *Server) SetAddress(addr string)

SetAddress sets the configured address of the server in a concurrency safe manner.

func (*Server) SetHostname

func (server *Server) SetHostname(host string)

SetHostname sets the configured hostname of the server in a concurrency safe manner.

func (*Server) SetMOTD

func (server *Server) SetMOTD(motd string)

SetMOTD sets the configured MOTD of the server in a concurrency safe manner.

func (*Server) SetNetwork

func (server *Server) SetNetwork(new string)

SetNetwork sets the configured network name of the server in a concurrency safe manner.

func (*Server) SetWelcome

func (server *Server) SetWelcome(msg string)

SetWelcome sets the configured welcome message of the server in a concurrency safe manner.

func (*Server) Welcome

func (server *Server) Welcome() string

Welcome returns the configured welcome message of the server in a concurrency safe manner.

type UModeReq

type UModeReq struct {
	Setter uint8
	Target uint8
}

UModeReq is used to define the required setter/target permission levels.

type User

type User struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

User holds all of the state in the context of a connected user.

func (*User) AddMode

func (user *User) AddMode(umode uint64)

AddMode appends the specified mode flag to the user in a concurrency-safe manner.

func (*User) DelMode

func (user *User) DelMode(umode uint64)

DelMode removes the specified mode flag from the user in a concurrency-safe manner.

func (*User) HigherPerms

func (user *User) HigherPerms(target uint8) bool

HigherPerms checks if the given target User has a higher permission level than the Given user being checked.

func (*User) Hostmask

func (user *User) Hostmask() string

Hostmask returns the string form of the full IRC hostmask. It will return the Vanity hostname insteead of the regular hostname if VanityEnabled is set to true, and the VanityHost is set in the User object.

<nick>!<username>@<hostname|vanityhost>

func (*User) Mode

func (user *User) Mode() uint64

Mode returns the mode field of the user in a concurrency-safe manner.

func (*User) ModeIsSet

func (user *User) ModeIsSet(umode uint64) bool

ModeIsSet checks if a given user mode is currently set in a concurrency-safe manner.

func (*User) Name

func (user *User) Name() string

Name returns the username field of the user in a concurrency-safe manner.

func (*User) Nick

func (user *User) Nick() string

Nick returns the nick field of the user in a concurrency-safe manner.

func (*User) Permission

func (user *User) Permission() uint8

Permission returns the permission field of the user in a concurrency-safe manner.

func (*User) RealHostmask

func (user *User) RealHostmask() string

RealHostmask returns the string form of the full IRC hostmask. It will not return the Vanity hostname even if VanityEnabled is set to true.

<nick>!<username>@<hostname>

func (*User) Realname

func (user *User) Realname() string

Realname returns the realname field of the user in a concurrency-safe manner.

func (*User) SetHostname

func (user *User) SetHostname(new string)

SetHostname sets the hostname field of the user in a concurrency-safe manner.

func (*User) SetName

func (user *User) SetName(new string)

SetName sets the username field of the user in a concurrency-safe manner.

func (*User) SetNick

func (user *User) SetNick(new string)

SetNick sets the nick field of the user in a concurrency-safe manner.

func (*User) SetPermission

func (user *User) SetPermission(new uint8)

SetPermission the permission field of the user in a concurrency-safe manner.

func (*User) SetRealname

func (user *User) SetRealname(new string)

SetRealname sets the realname field of the user in a concurrency-safe manner.

func (*User) SetVanityEnabled

func (user *User) SetVanityEnabled(new bool)

SetVanityEnabled the vanityenabled field of the user in a concurrency-safe manner.

func (*User) SetVanityHost

func (user *User) SetVanityHost(new string)

SetVanityHost sets the vanityhost field of the user in a concurrency-safe manner.

func (*User) VanityEnabled

func (user *User) VanityEnabled() bool

VanityEnabled returns the vanityenabled field of the user in a concurrency-safe manner.

func (*User) VanityHost

func (user *User) VanityHost() string

VanityHost returns the vanityhost field of the user in a concurrency-safe manner.

type UserMap

type UserMap struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

UserMap is a simple map[string]*User wrapped with a concurrent-safe API

func NewUserMap

func NewUserMap() *UserMap

NewUserMap initializes and returns a pointer to a new UserMap instance.

func (*UserMap) Add

func (m *UserMap) Add(key string, value *User) error

Add is used to add a key/value to the map. Returns an error if the key already exists.

func (*UserMap) Del

func (m *UserMap) Del(key string) error

Del is used to remove a key/value from the map. Returns an error if the key does not exist.

func (*UserMap) Exists

func (m *UserMap) Exists(key string) bool

Exists is used by external callers to check if a value exists in the map and returns a boolean with the result.

func (*UserMap) ForEach

func (m *UserMap) ForEach(do func(*User))

ForEach will call the provided function for each entry in the UserMap

func (*UserMap) Get

func (m *UserMap) Get(key string) (*User, error)

Get is used to get a key/value from the map. Returns an error if the key does not exist.

func (*UserMap) Length

func (m *UserMap) Length() int

Length returns the length of the underlying map.

func (*UserMap) Set

func (m *UserMap) Set(key string, value *User) error

Set is used to change an existing key/value in the map. Returns an error if the key does not exist.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL