From 26ad55851febe624145ac807dbf59376ba669eaf Mon Sep 17 00:00:00 2001 From: Treeki Date: Tue, 21 Jan 2014 01:01:43 +0100 Subject: refactoring: add event handling functions to the Server/IRCServer interface --- core.h | 17 +++++++++++++++-- ircserver.cpp | 28 ++++++++++++++++++++++++++++ mobileclient.cpp | 14 +++++++++++--- netcore.cpp | 13 +++++++++++-- server.cpp | 26 +++++++++++++++----------- socketcommon.cpp | 7 +++++-- 6 files changed, 85 insertions(+), 20 deletions(-) diff --git a/core.h b/core.h index cd45356..8e2d317 100644 --- a/core.h +++ b/core.h @@ -55,7 +55,7 @@ struct SocketRWCommon { SocketRWCommon(NetCore *_netCore); virtual ~SocketRWCommon(); - void tryTLSHandshake(); + bool tryTLSHandshake(); virtual void close(); void readAction(); @@ -154,16 +154,23 @@ public: void tryConnectPhase(); void connectionSuccessful(); + void sendLine(const char *line); // protect me! void close(); private: void processReadBuffer(); - void handleLine(char *line, int size); + +public: + virtual void connectedEvent() = 0; // PRIVATE ME +private: + virtual void disconnectedEvent() = 0; + virtual void lineReceivedEvent(char *line, int size) = 0; }; struct IRCNetworkConfig { char hostname[512]; char nickname[128]; + char username[128]; char realname[128]; char password[128]; int port; @@ -177,6 +184,12 @@ struct IRCServer : Server { IRCServer(Bouncer *_bouncer); void connect(); + + // Events! +private: + virtual void connectedEvent(); + virtual void disconnectedEvent(); + virtual void lineReceivedEvent(char *line, int size); }; diff --git a/ircserver.cpp b/ircserver.cpp index 94456dc..8ccdbb9 100644 --- a/ircserver.cpp +++ b/ircserver.cpp @@ -7,3 +7,31 @@ IRCServer::IRCServer(Bouncer *_bouncer) : Server(_bouncer) { void IRCServer::connect() { Server::connect(config.hostname, config.port, config.useTls); } + + +void IRCServer::connectedEvent() { + printf("[IRCServer:%p] connectedEvent\n", this); + + char buf[2048]; + + if (strlen(config.password) > 0) { + sprintf(buf, "PASS %s", config.password); + sendLine(buf); + } + + sprintf(buf, "USER %s 0 * :%s\r\nNICK %s", + config.username, config.realname, config.nickname); + sendLine(buf); +} +void IRCServer::disconnectedEvent() { + printf("[IRCServer:%p] disconnectedEvent\n", this); +} +void IRCServer::lineReceivedEvent(char *line, int size) { + printf("[%d] { %s }\n", size, line); + + Buffer pkt; + pkt.writeStr(line, size); + for (int i = 0; i < bouncer->clientCount; i++) + if (bouncer->clients[i]->authState == Client::AS_AUTHED) + bouncer->clients[i]->sendPacket(Packet::B2C_STATUS, pkt); +} diff --git a/mobileclient.cpp b/mobileclient.cpp index 2377a35..c6be33a 100644 --- a/mobileclient.cpp +++ b/mobileclient.cpp @@ -36,8 +36,12 @@ void MobileClient::handleDebugCommand(char *line, int size) { } else if (strncmp(&line[1], "ddsrv ", 6) == 0) { IRCServer *srv = new IRCServer(bouncer); strcpy(srv->config.hostname, &line[7]); - srv->config.port = 1191; srv->config.useTls = (line[0] == 's'); + srv->config.port = (line[0] == 's') ? 1191 : 6667; + strcpy(srv->config.nickname, "Ninjifox"); + strcpy(srv->config.username, "boop"); + strcpy(srv->config.realname, "boop"); + strcpy(srv->config.password, ""); bouncer->registerServer(srv); Buffer pkt; @@ -45,14 +49,18 @@ void MobileClient::handleDebugCommand(char *line, int size) { for (int i = 0; i < netCore->clientCount; i++) netCore->clients[i]->sendPacket(Packet::B2C_STATUS, pkt); + } else if (strncmp(line, "srvpw", 5) == 0) { + int sid = line[5] - '0'; + // ugly hack, fuck casting, will fix later + strcpy(((IRCServer*)netCore->servers[sid])->config.password, &line[7]); + } else if (strncmp(line, "connsrv", 7) == 0) { int sid = line[7] - '0'; // ugly hack, fuck casting, will fix later ((IRCServer*)netCore->servers[sid])->connect(); } else if (line[0] >= '0' && line[0] <= '9') { int sid = line[0] - '0'; - netCore->servers[sid]->outputBuf.append(&line[1], size - 1); - netCore->servers[sid]->outputBuf.append("\r\n", 2); + netCore->servers[sid]->sendLine(&line[1]); } } else { } diff --git a/netcore.cpp b/netcore.cpp index 684d319..27769a6 100644 --- a/netcore.cpp +++ b/netcore.cpp @@ -131,8 +131,10 @@ int NetCore::execute() { for (int i = 0; i < serverCount; i++) { if (servers[i]->state == Server::CS_WAITING_DNS) servers[i]->tryConnectPhase(); - else if (servers[i]->state == Server::CS_TLS_HANDSHAKE) - servers[i]->tryTLSHandshake(); + else if (servers[i]->state == Server::CS_TLS_HANDSHAKE) { + if (servers[i]->tryTLSHandshake()) + servers[i]->connectedEvent(); + } if (servers[i]->sock != -1) { if (servers[i]->sock > maxFD) @@ -238,6 +240,13 @@ int NetCore::execute() { shutdown(listener, SHUT_RDWR); close(listener); + for (int i = 0; i < serverCount; i++) + delete servers[i]; + for (int i = 0; i < clientCount; i++) + delete clients[i]; + + serverCount = clientCount = 0; + return 0; } diff --git a/server.cpp b/server.cpp index e892aa9..820c579 100644 --- a/server.cpp +++ b/server.cpp @@ -7,19 +7,11 @@ Server::Server(NetCore *_netCore) : SocketRWCommon(_netCore) { Server::~Server() { if (dnsQueryId != -1) DNS::closeQuery(dnsQueryId); + close(); } -void Server::handleLine(char *line, int size) { - printf("[%d] { %s }\n", size, line); - - Buffer pkt; - pkt.writeStr(line, size); - for (int i = 0; i < netCore->clientCount; i++) - if (netCore->clients[i]->authState == Client::AS_AUTHED) - netCore->clients[i]->sendPacket(Packet::B2C_STATUS, pkt); -} void Server::processReadBuffer() { // Try to process as many lines as we can char *buf = inputBuf.data(); @@ -30,7 +22,7 @@ void Server::processReadBuffer() { if (buf[pos] == '\r' || buf[pos] == '\n') { if (pos > lineBegin) { buf[pos] = 0; - handleLine(&buf[lineBegin], pos - lineBegin); + lineReceivedEvent(&buf[lineBegin], pos - lineBegin); } lineBegin = pos + 1; @@ -43,6 +35,10 @@ void Server::processReadBuffer() { inputBuf.trimFromStart(lineBegin); } +void Server::sendLine(const char *line) { + outputBuf.append(line, strlen(line)); + outputBuf.append("\r\n", 2); +} void Server::connect(const char *hostname, int _port, bool _useTls) { @@ -120,6 +116,8 @@ void Server::connectionSuccessful() { // Do we need to do any TLS junk? if (useTls) { + state = CS_TLS_HANDSHAKE; + int initRet = gnutls_init(&tls, GNUTLS_CLIENT); if (initRet != GNUTLS_E_SUCCESS) { printf("[Server::connectionSuccessful] gnutls_init borked\n"); @@ -137,17 +135,23 @@ void Server::connectionSuccessful() { gnutls_transport_set_int(tls, sock); tlsActive = true; - state = CS_TLS_HANDSHAKE; + } else { + connectedEvent(); } } void Server::close() { + int saveState = state; + SocketRWCommon::close(); if (dnsQueryId != -1) { DNS::closeQuery(dnsQueryId); dnsQueryId = -1; } + + if (saveState == CS_CONNECTED) + disconnectedEvent(); } diff --git a/socketcommon.cpp b/socketcommon.cpp index b419c93..e98b837 100644 --- a/socketcommon.cpp +++ b/socketcommon.cpp @@ -32,13 +32,13 @@ bool SocketRWCommon::hasTlsPendingData() const { return false; } -void SocketRWCommon::tryTLSHandshake() { +bool SocketRWCommon::tryTLSHandshake() { int hsRet = gnutls_handshake(tls); if (gnutls_error_is_fatal(hsRet)) { printf("[SocketRWCommon::tryTLSHandshake] gnutls_handshake borked\n"); gnutls_perror(hsRet); close(); - return; + return false; } if (hsRet == GNUTLS_E_SUCCESS) { @@ -49,7 +49,10 @@ void SocketRWCommon::tryTLSHandshake() { outputBuf.clear(); printf("[SocketRWCommon connected via SSL!]\n"); + return true; } + + return false; } void SocketRWCommon::close() { -- cgit v1.2.3