diff options
author | Treeki <treeki@gmail.com> | 2014-01-20 10:24:36 +0100 |
---|---|---|
committer | Treeki <treeki@gmail.com> | 2014-01-20 10:24:36 +0100 |
commit | c82c6f3671206a945d4a40227246ec5df4460232 (patch) | |
tree | d558b3aad4d5ba25deddf77925a52a5aecbefc95 /server.cpp | |
parent | 52b1b88c9ce0f92235963cf1485b49df58cfbe87 (diff) | |
download | bounce4-c82c6f3671206a945d4a40227246ec5df4460232.tar.gz bounce4-c82c6f3671206a945d4a40227246ec5df4460232.zip |
split every class up into a separate file
Diffstat (limited to '')
-rw-r--r-- | server.cpp | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/server.cpp b/server.cpp new file mode 100644 index 0000000..5739159 --- /dev/null +++ b/server.cpp @@ -0,0 +1,149 @@ +#include "core.h" +#include "dns.h" + +Server::Server(NetCore *_netCore) : SocketRWCommon(_netCore) { + dnsQueryId = -1; + ircUseTls = false; +} +Server::~Server() { + if (dnsQueryId != -1) + DNS::closeQuery(dnsQueryId); +} + + + +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(); + int bufSize = inputBuf.size(); + int lineBegin = 0, pos = 0; + + while (pos < bufSize) { + if (buf[pos] == '\r' || buf[pos] == '\n') { + if (pos > lineBegin) { + buf[pos] = 0; + handleLine(&buf[lineBegin], pos - lineBegin); + } + + lineBegin = pos + 1; + } + + pos++; + } + + // If we managed to handle anything, lop it off the buffer + inputBuf.trimFromStart(lineBegin); +} + + + +void Server::beginConnect() { + if (state == CS_DISCONNECTED) { + DNS::closeQuery(dnsQueryId); // just in case + dnsQueryId = DNS::makeQuery(ircHostname); + + if (dnsQueryId == -1) { + // TODO: better error reporting + printf("DNS query failed!\n"); + } else { + state = CS_WAITING_DNS; + } + } +} + +void Server::tryConnectPhase() { + if (state == CS_WAITING_DNS) { + in_addr result; + bool isError; + + if (DNS::checkQuery(dnsQueryId, &result, &isError)) { + DNS::closeQuery(dnsQueryId); + dnsQueryId = -1; + + if (isError) { + printf("DNS query failed at phase 2!\n"); + state = CS_DISCONNECTED; + } else { + // OK, if there was no error, we can go ahead and do this... + + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock == -1) { + perror("[Server] Failed to socket()"); + close(); + return; + } + + if (!setSocketNonBlocking(sock)) { + perror("[Server] Could not set non-blocking"); + close(); + return; + } + + // We have our non-blocking socket, let's try connecting! + sockaddr_in outAddr; + outAddr.sin_family = AF_INET; + outAddr.sin_port = htons(ircPort); + outAddr.sin_addr.s_addr = result.s_addr; + + if (connect(sock, (sockaddr *)&outAddr, sizeof(outAddr)) == -1) { + if (errno == EINPROGRESS) { + state = CS_WAITING_CONNECT; + } else { + perror("[Server] Could not connect"); + close(); + } + } else { + // Whoa, we're connected? Neat. + connectionSuccessful(); + } + } + } + } +} + +void Server::connectionSuccessful() { + state = CS_CONNECTED; + + inputBuf.clear(); + outputBuf.clear(); + + // Do we need to do any TLS junk? + if (ircUseTls) { + int initRet = gnutls_init(&tls, GNUTLS_CLIENT); + if (initRet != GNUTLS_E_SUCCESS) { + printf("[Server::connectionSuccessful] gnutls_init borked\n"); + gnutls_perror(initRet); + close(); + return; + } + + // TODO: error check this + const char *errPos; + gnutls_priority_set_direct(tls, "NORMAL", &errPos); + + gnutls_credentials_set(tls, GNUTLS_CRD_CERTIFICATE, g_serverCreds); + + gnutls_transport_set_int(tls, sock); + + tlsActive = true; + state = CS_TLS_HANDSHAKE; + } +} + +void Server::close() { + SocketRWCommon::close(); + + if (dnsQueryId != -1) { + DNS::closeQuery(dnsQueryId); + dnsQueryId = -1; + } +} |