IRC_SERVER
By @hyunjunk (hyunjun2372@gmail.com)
Loading...
Searching...
No Matches
IRC::Server Class Reference

#include <Server.hpp>

Public Member Functions

EIrcErrorCode Startup ()
 Initialize resources and start the server event loop.
 
 ~Server ()
 

Static Public Member Functions

static EIrcErrorCode CreateServer (Server **outPtrServer, const std::string &serverName, const unsigned short port, const std::string &password)
 Create a server instance.
 

Private Types

typedef IRC::EIrcErrorCode(Server::* ClientCommandFuncPtr) (SharedPtr< ClientControlBlock > client, const std::vector< char * > &arguments)
 Client command execution function type.
 

Private Member Functions

 Server (const std::string &serverName, const unsigned short port, const std::string &password)
 
UNUSED Serveroperator= (const Server &rhs)
 
EIrcErrorCode eventLoop ()
 A main event loop of the server.
 
EIrcErrorCode destroyResources ()
 Destroy all resources of the server.
 
SharedPtr< ClientControlBlockgetClientFromKeventUdata (kevent_t &event) const
 Get SharedPtr to the ClientControlBlock from the kevent's udata.
 
bool registerClient (SharedPtr< ClientControlBlock > client)
 Register a client to the server.
 
void joinClientToChannel (SharedPtr< ClientControlBlock > client, SharedPtr< ChannelControlBlock > channel)
 Join a client to the exist channel without any error/permission check.
 
void partClientFromChannel (SharedPtr< ClientControlBlock > client, SharedPtr< ChannelControlBlock > channel)
 Part a client from the channel without any error/permission check.
 
SharedPtr< ClientControlBlockfindClientGlobal (const std::string &nickname)
 
SharedPtr< ChannelControlBlockfindChannelGlobal (const std::string &channelName)
 

Private Attributes

std::string mServerName
 
short mServerPort
 
std::string mServerPassword
 
int mhListenSocket
 
std::vector< SharedPtr< ClientControlBlock > > mClientReleaseQueue
 Queue to release expired clients.
 
std::map< std::string, WeakPtr< ChannelControlBlock > > mChannels
 Channel name to channel map.
 

Kqueue

Data in the udata of kevent is the controlBlock of the SharedPtr to corresponding ClientControlBlock (except listensocket).

See also
int mhKqueue
 
std::vector< kevent_tmEventRegistrationQueue
 

Client lists

Warning
Do not release a client if the client's event is still exists in the kqueue.
std::vector< SharedPtr< ClientControlBlock > > mUnregistedClients
 Nickname to client map.
 
std::map< std::string, SharedPtr< ClientControlBlock > > mClients
 Nickname to client map.
 

Message Processing

EIrcErrorCode separateMsgsFromClientRecvMsgs (SharedPtr< ClientControlBlock > client, std::vector< SharedPtr< MsgBlock > > &outSeparatedMsgs)
 Separate all separable messages in the client's ClientControlBlock::RecvMsgBlocks.
 
EIrcErrorCode processClientMsg (SharedPtr< ClientControlBlock > client, SharedPtr< MsgBlock > msg)
 Execute and reply the client's single message.
 

Client command execution

Execute and reply the client command.

Each function handles permission and validity checks, execution, and all replies.

IRC::EIrcErrorCode executeClientCommand_PASS (SharedPtr< ClientControlBlock > client, const std::vector< char * > &arguments)
 
IRC::EIrcErrorCode executeClientCommand_NICK (SharedPtr< ClientControlBlock > client, const std::vector< char * > &arguments)
 
IRC::EIrcErrorCode executeClientCommand_USER (SharedPtr< ClientControlBlock > client, const std::vector< char * > &arguments)
 
IRC::EIrcErrorCode executeClientCommand_JOIN (SharedPtr< ClientControlBlock > client, const std::vector< char * > &arguments)
 
IRC::EIrcErrorCode executeClientCommand_MODE (SharedPtr< ClientControlBlock > client, const std::vector< char * > &arguments)
 
IRC::EIrcErrorCode executeClientCommand_PRIVMSG (SharedPtr< ClientControlBlock > client, const std::vector< char * > &arguments)
 
IRC::EIrcErrorCode executeClientCommand_TOPIC (SharedPtr< ClientControlBlock > client, const std::vector< char * > &arguments)
 
IRC::EIrcErrorCode executeClientCommand_KICK (SharedPtr< ClientControlBlock > client, const std::vector< char * > &arguments)
 
IRC::EIrcErrorCode executeClientCommand_INVITE (SharedPtr< ClientControlBlock > client, const std::vector< char * > &arguments)
 
IRC::EIrcErrorCode executeClientCommand_QUIT (SharedPtr< ClientControlBlock > client, const std::vector< char * > &arguments)
 
IRC::EIrcErrorCode executeClientCommand_PART (SharedPtr< ClientControlBlock > client, const std::vector< char * > &arguments)
 

Client disconnection

Note
The releases of the disconnected clients are deferred to the next main event loop for the remaining kevents of the client.
EIrcErrorCode forceDisconnectClient (SharedPtr< ClientControlBlock > client, const std::string quitMessage="")
 Close the client socket and release the client.
 
EIrcErrorCode disconnectClient (SharedPtr< ClientControlBlock > client, const std::string quitMessage="")
 Mark the client's bExpired flag and block the messages from the client, then close the socket after remaining messages are sent.
 

Message sending

Note
  • Do not modify the passed message after calling this function.
  • No check permission of the client to send the message.
void sendMsgToClient (SharedPtr< ClientControlBlock > client, SharedPtr< MsgBlock > msg)
 Send a message to client.
 
void sendMsgToChannel (SharedPtr< ChannelControlBlock > channel, SharedPtr< MsgBlock > msg, SharedPtr< ClientControlBlock > exceptClient=NULL)
 Send a message to channel members.
 
void sendMsgToConnectedChannels (SharedPtr< ClientControlBlock > client, SharedPtr< MsgBlock > msg)
 Send a message to channels the client is connected.
 

Logging

void logErrorCode (EIrcErrorCode errorCode) const
 
void logMessage (const std::string &message) const
 
void logVerbose (const std::string &message) const
 

Detailed Description

Note
See [ Server Event Loop Process Flow ] before reading implementation details.

Member Typedef Documentation

◆ ClientCommandFuncPtr

typedef IRC::EIrcErrorCode(Server::* IRC::Server::ClientCommandFuncPtr) (SharedPtr< ClientControlBlock > client, const std::vector< char * > &arguments)
private

Client command execution function type.

See also
ClientCommandExecution section in IRC::Server class

Constructor & Destructor Documentation

◆ ~Server()

IRC::Server::~Server ( )

◆ Server()

IRC::Server::Server ( const std::string & serverName,
const unsigned short port,
const std::string & password )
private

Member Function Documentation

◆ CreateServer()

EIrcErrorCode IRC::Server::CreateServer ( Server ** outPtrServer,
const std::string & serverName,
const unsigned short port,
const std::string & password )
static

Create a server instance.

Parameters
outPtrServer[out] Pointer to receive an instance.
portPort number to listen.
passwordPassword to access server. see Constants::SVR_PASS_MIN, Constants::SVR_PASS_MAX

◆ Startup()

EIrcErrorCode IRC::Server::Startup ( )

Initialize resources and start the server event loop.

Initialize kqueue and resources and register listen socket to kqueue. And then call eventLoop() to start the server.

Note
  • Blocking until the server is terminated.
  • All non-static methods must be called after this function is called.

◆ operator=()

Server & IRC::Server::operator= ( const Server & rhs)
private
Warning
Copy constructor is not allowed.

◆ eventLoop()

EIrcErrorCode IRC::Server::eventLoop ( )
private

A main event loop of the server.

◆ destroyResources()

EIrcErrorCode IRC::Server::destroyResources ( )
private

Destroy all resources of the server.

Note
After calling this function, the server instance is no longer available.

◆ separateMsgsFromClientRecvMsgs()

EIrcErrorCode IRC::Server::separateMsgsFromClientRecvMsgs ( SharedPtr< ClientControlBlock > client,
std::vector< SharedPtr< MsgBlock > > & outSeparatedMsgs )
private

Separate all separable messages in the client's ClientControlBlock::RecvMsgBlocks.

Parameters
clientA client to separate messages.
outSeparatedMsgs[out] Vector to receive the separated messages without CR-LF. If the vector is not empty, the separated messages are appended to the end of the vector.
See also
ClientControlBlock::RecvMsgBlockCursor

◆ processClientMsg()

EIrcErrorCode IRC::Server::processClientMsg ( SharedPtr< ClientControlBlock > client,
SharedPtr< MsgBlock > msg )
private

Execute and reply the client's single message.

Parameters
clientThe client to process the message.
msgThe single message to process. It contains CR-LF. And it will be modified during the processing.
See also
Reply message making functions

◆ getClientFromKeventUdata()

SharedPtr< ClientControlBlock > IRC::Server::getClientFromKeventUdata ( kevent_t & event) const
inlineprivate

Get SharedPtr to the ClientControlBlock from the kevent's udata.

◆ executeClientCommand_PASS()

EIrcErrorCode IRC::Server::executeClientCommand_PASS ( SharedPtr< ClientControlBlock > client,
const std::vector< char * > & arguments )
private
Parameters
client[in] The client to process the command.
arguments[in] Unvalidated arguments that separated by space.
Example: "JOIN #channel1,#channel2 key1 key2 :h ello!@:world"
arguments[0] = "#channel1,#channel2"
arguments[1] = "key1"
arguments[2] = "key2"
arguments[3] = "h ello!@:world"
Returns
The error code of the command execution.
See also
Server/ClientCommand/<COMMAND>.cpp

◆ executeClientCommand_NICK()

EIrcErrorCode IRC::Server::executeClientCommand_NICK ( SharedPtr< ClientControlBlock > client,
const std::vector< char * > & arguments )
private
Parameters
client[in] The client to process the command.
arguments[in] Unvalidated arguments that separated by space.
Example: "JOIN #channel1,#channel2 key1 key2 :h ello!@:world"
arguments[0] = "#channel1,#channel2"
arguments[1] = "key1"
arguments[2] = "key2"
arguments[3] = "h ello!@:world"
Returns
The error code of the command execution.
See also
Server/ClientCommand/<COMMAND>.cpp

◆ executeClientCommand_USER()

EIrcErrorCode IRC::Server::executeClientCommand_USER ( SharedPtr< ClientControlBlock > client,
const std::vector< char * > & arguments )
private
Parameters
client[in] The client to process the command.
arguments[in] Unvalidated arguments that separated by space.
Example: "JOIN #channel1,#channel2 key1 key2 :h ello!@:world"
arguments[0] = "#channel1,#channel2"
arguments[1] = "key1"
arguments[2] = "key2"
arguments[3] = "h ello!@:world"
Returns
The error code of the command execution.
See also
Server/ClientCommand/<COMMAND>.cpp

◆ executeClientCommand_JOIN()

EIrcErrorCode IRC::Server::executeClientCommand_JOIN ( SharedPtr< ClientControlBlock > client,
const std::vector< char * > & arguments )
private
Parameters
client[in] The client to process the command.
arguments[in] Unvalidated arguments that separated by space.
Example: "JOIN #channel1,#channel2 key1 key2 :h ello!@:world"
arguments[0] = "#channel1,#channel2"
arguments[1] = "key1"
arguments[2] = "key2"
arguments[3] = "h ello!@:world"
Returns
The error code of the command execution.
See also
Server/ClientCommand/<COMMAND>.cpp

◆ executeClientCommand_MODE()

EIrcErrorCode IRC::Server::executeClientCommand_MODE ( SharedPtr< ClientControlBlock > client,
const std::vector< char * > & arguments )
private
Parameters
client[in] The client to process the command.
arguments[in] Unvalidated arguments that separated by space.
Example: "JOIN #channel1,#channel2 key1 key2 :h ello!@:world"
arguments[0] = "#channel1,#channel2"
arguments[1] = "key1"
arguments[2] = "key2"
arguments[3] = "h ello!@:world"
Returns
The error code of the command execution.
See also
Server/ClientCommand/<COMMAND>.cpp

◆ executeClientCommand_PRIVMSG()

EIrcErrorCode IRC::Server::executeClientCommand_PRIVMSG ( SharedPtr< ClientControlBlock > client,
const std::vector< char * > & arguments )
private
Parameters
client[in] The client to process the command.
arguments[in] Unvalidated arguments that separated by space.
Example: "JOIN #channel1,#channel2 key1 key2 :h ello!@:world"
arguments[0] = "#channel1,#channel2"
arguments[1] = "key1"
arguments[2] = "key2"
arguments[3] = "h ello!@:world"
Returns
The error code of the command execution.
See also
Server/ClientCommand/<COMMAND>.cpp

◆ executeClientCommand_TOPIC()

EIrcErrorCode IRC::Server::executeClientCommand_TOPIC ( SharedPtr< ClientControlBlock > client,
const std::vector< char * > & arguments )
private
Parameters
client[in] The client to process the command.
arguments[in] Unvalidated arguments that separated by space.
Example: "JOIN #channel1,#channel2 key1 key2 :h ello!@:world"
arguments[0] = "#channel1,#channel2"
arguments[1] = "key1"
arguments[2] = "key2"
arguments[3] = "h ello!@:world"
Returns
The error code of the command execution.
See also
Server/ClientCommand/<COMMAND>.cpp

◆ executeClientCommand_KICK()

EIrcErrorCode IRC::Server::executeClientCommand_KICK ( SharedPtr< ClientControlBlock > client,
const std::vector< char * > & arguments )
private
Parameters
client[in] The client to process the command.
arguments[in] Unvalidated arguments that separated by space.
Example: "JOIN #channel1,#channel2 key1 key2 :h ello!@:world"
arguments[0] = "#channel1,#channel2"
arguments[1] = "key1"
arguments[2] = "key2"
arguments[3] = "h ello!@:world"
Returns
The error code of the command execution.
See also
Server/ClientCommand/<COMMAND>.cpp

◆ executeClientCommand_INVITE()

EIrcErrorCode IRC::Server::executeClientCommand_INVITE ( SharedPtr< ClientControlBlock > client,
const std::vector< char * > & arguments )
private
Parameters
client[in] The client to process the command.
arguments[in] Unvalidated arguments that separated by space.
Example: "JOIN #channel1,#channel2 key1 key2 :h ello!@:world"
arguments[0] = "#channel1,#channel2"
arguments[1] = "key1"
arguments[2] = "key2"
arguments[3] = "h ello!@:world"
Returns
The error code of the command execution.
See also
Server/ClientCommand/<COMMAND>.cpp

◆ executeClientCommand_QUIT()

EIrcErrorCode IRC::Server::executeClientCommand_QUIT ( SharedPtr< ClientControlBlock > client,
const std::vector< char * > & arguments )
private
Parameters
client[in] The client to process the command.
arguments[in] Unvalidated arguments that separated by space.
Example: "JOIN #channel1,#channel2 key1 key2 :h ello!@:world"
arguments[0] = "#channel1,#channel2"
arguments[1] = "key1"
arguments[2] = "key2"
arguments[3] = "h ello!@:world"
Returns
The error code of the command execution.
See also
Server/ClientCommand/<COMMAND>.cpp

◆ executeClientCommand_PART()

EIrcErrorCode IRC::Server::executeClientCommand_PART ( SharedPtr< ClientControlBlock > client,
const std::vector< char * > & arguments )
private
Parameters
client[in] The client to process the command.
arguments[in] Unvalidated arguments that separated by space.
Example: "JOIN #channel1,#channel2 key1 key2 :h ello!@:world"
arguments[0] = "#channel1,#channel2"
arguments[1] = "key1"
arguments[2] = "key2"
arguments[3] = "h ello!@:world"
Returns
The error code of the command execution.
See also
Server/ClientCommand/<COMMAND>.cpp

◆ forceDisconnectClient()

EIrcErrorCode IRC::Server::forceDisconnectClient ( SharedPtr< ClientControlBlock > client,
const std::string quitMessage = "" )
private

Close the client socket and release the client.

◆ disconnectClient()

EIrcErrorCode IRC::Server::disconnectClient ( SharedPtr< ClientControlBlock > client,
const std::string quitMessage = "" )
private

Mark the client's bExpired flag and block the messages from the client, then close the socket after remaining messages are sent.

Sending to the client is not able after calling this function.

◆ registerClient()

bool IRC::Server::registerClient ( SharedPtr< ClientControlBlock > client)
private

Register a client to the server.

Reply the result of the registration.

Parameters
clientThe client to register.
Returns
Result of the registration.

◆ joinClientToChannel()

void IRC::Server::joinClientToChannel ( SharedPtr< ClientControlBlock > client,
SharedPtr< ChannelControlBlock > channel )
private

Join a client to the exist channel without any error/permission check.

◆ partClientFromChannel()

void IRC::Server::partClientFromChannel ( SharedPtr< ClientControlBlock > client,
SharedPtr< ChannelControlBlock > channel )
private

Part a client from the channel without any error/permission check.

◆ findClientGlobal()

SharedPtr< ClientControlBlock > IRC::Server::findClientGlobal ( const std::string & nickname)
private

◆ findChannelGlobal()

SharedPtr< ChannelControlBlock > IRC::Server::findChannelGlobal ( const std::string & channelName)
private

◆ sendMsgToClient()

void IRC::Server::sendMsgToClient ( SharedPtr< ClientControlBlock > client,
SharedPtr< MsgBlock > msg )
private

Send a message to client.

Parameters
clientThe client to send the message.
msgThe message to send. It can contain CR-LF or not.

◆ sendMsgToChannel()

void IRC::Server::sendMsgToChannel ( SharedPtr< ChannelControlBlock > channel,
SharedPtr< MsgBlock > msg,
SharedPtr< ClientControlBlock > exceptClient = NULL )
private

Send a message to channel members.

Parameters
channelThe channel to send the message.
msgThe message to send. It can contain CR-LF or not.
clientA client to exclude from the message sending.

◆ sendMsgToConnectedChannels()

void IRC::Server::sendMsgToConnectedChannels ( SharedPtr< ClientControlBlock > client,
SharedPtr< MsgBlock > msg )
private

Send a message to channels the client is connected.

Parameters
clientThe client to send the message. This client is excluded from the message sending.
msgThe message to send. It can contain CR-LF or not.

◆ logErrorCode()

void IRC::Server::logErrorCode ( EIrcErrorCode errorCode) const
private

◆ logMessage()

void IRC::Server::logMessage ( const std::string & message) const
private

◆ logVerbose()

void IRC::Server::logVerbose ( const std::string & message) const
private

Member Data Documentation

◆ mServerName

std::string IRC::Server::mServerName
private

◆ mServerPort

short IRC::Server::mServerPort
private

◆ mServerPassword

std::string IRC::Server::mServerPassword
private

◆ mhListenSocket

int IRC::Server::mhListenSocket
private

◆ mhKqueue

int IRC::Server::mhKqueue
private

◆ mEventRegistrationQueue

std::vector<kevent_t> IRC::Server::mEventRegistrationQueue
private

◆ mUnregistedClients

std::vector< SharedPtr< ClientControlBlock > > IRC::Server::mUnregistedClients
private

Nickname to client map.

◆ mClients

std::map< std::string, SharedPtr< ClientControlBlock > > IRC::Server::mClients
private

Nickname to client map.

◆ mClientReleaseQueue

std::vector< SharedPtr< ClientControlBlock > > IRC::Server::mClientReleaseQueue
private

Queue to release expired clients.

See also
ClientDisconnection section in IRC::Server class

◆ mChannels

std::map< std::string, WeakPtr< ChannelControlBlock > > IRC::Server::mChannels
private

Channel name to channel map.

Warning

Caution for using WeakPtr

[한국어]

WeakPtr이 Expired 되어도 map에서 자동으로 제거되지 않습니다.
map을 직접 조작하는 경우 다음과 같은 문제를 주의해야 합니다.
만약 expired 된 엔트리가 제거되지 않은 상태에서 동일한 key로 map::insert() 를 시도하면 덮어씌워지지 않습니다. (map::insert()는 동일한 key가 있을 경우 실패합니다.)
이러한 경우를 방지하기 위해 expired 된 엔트리를 수동으로 제거하거나, map::insert() 대신 map::operator[] 를 사용해야합니다. (operator[]는 동일한 key가 있을 경우 덮어씌웁니다.)
그러므로 가능한 joinClientToChannel(), partClientFromChannel() 등 미리 구현된 함수를 사용해야합니다.

[English]

Even if WeakPtr is Expired, it is not automatically removed from the map.
When directly manipulating the map, you should be aware of the following issues.
If an expired entry is not removed and an attempt is made to map::insert() with the same key, it will not be overwritten. (map::insert() fails if the same key exists.)
To prevent this, you must manually remove the expired entry or use map::operator[] instead of map::insert(). (operator[] overwrites if the same key exists.)
Thus, you should use pre-implemented functions such as joinClientToChannel(), partClientFromChannel().


The documentation for this class was generated from the following files: