From b0923b2b12cb3e191aecd0c8b760985b02c3777a Mon Sep 17 00:00:00 2001 From: JustinAJ Date: Thu, 20 Aug 2015 04:05:27 -0400 Subject: [PATCH] Sockets now use a buffer, instead of a C-Style string. Updated IRC::Client default address. --- Jupiter/IRC_Client.cpp | 6 +- Jupiter/SecureSocket.cpp | 19 +++-- Jupiter/Socket.cpp | 157 ++++++++++++++++++--------------------- Jupiter/Socket.h | 81 ++++++++++---------- 4 files changed, 130 insertions(+), 133 deletions(-) diff --git a/Jupiter/IRC_Client.cpp b/Jupiter/IRC_Client.cpp index eeee2df..57b5dff 100644 --- a/Jupiter/IRC_Client.cpp +++ b/Jupiter/IRC_Client.cpp @@ -125,7 +125,7 @@ Jupiter::IRC::Client::Client(const Jupiter::ReadableString &configSection) Jupiter::IRC::Client::Config->readFile(CONFIG_INI); } Jupiter::IRC::Client::data_->configSectionName = configSection; - Jupiter::IRC::Client::data_->serverHostname = Jupiter::IRC::Client::readConfigValue("Hostname"_jrs, "irc.tibitek.com"_jrs); + Jupiter::IRC::Client::data_->serverHostname = Jupiter::IRC::Client::readConfigValue("Hostname"_jrs, "irc.cncirc.net"_jrs); Jupiter::IRC::Client::data_->logFileName = Jupiter::IRC::Client::readConfigValue("LogFile"_jrs); Jupiter::IRC::Client::data_->nickname = Jupiter::IRC::Client::readConfigValue("Nick"_jrs, "Jupiter"_jrs); @@ -924,8 +924,8 @@ int Jupiter::IRC::Client::primaryHandler() if (command.equals("PING")) response += message; else if (command.equals("VERSION")) response += Jupiter::version; else if (command.equals("FINGER")) response += "Oh, yeah, a little to the left."; - else if (command.equals("SOURCE")) response += "irc.tibitek.com"; - else if (command.equals("USERINFO")) response += "Hey, I'm Jupiter! If you have questions, ask Justin! (irc.tibitek.com)"; + else if (command.equals("SOURCE")) response += "https://github.com/JAJames/Jupiter"; + else if (command.equals("USERINFO")) response += "Hey, I'm Jupiter! If you have questions, ask Agent! (irc.cncirc.net)"; else if (command.equals("CLIENTINFO")) response += "I'll tell you what I don't know: This command!"; else if (command.equals("TIME")) response += getTime(); else if (command.equals("ERRMSG")) response += message; diff --git a/Jupiter/SecureSocket.cpp b/Jupiter/SecureSocket.cpp index 819fb8a..0d10f93 100644 --- a/Jupiter/SecureSocket.cpp +++ b/Jupiter/SecureSocket.cpp @@ -177,16 +177,25 @@ bool Jupiter::SecureSocket::connect(const char *hostname, unsigned short iPort, int Jupiter::SecureSocket::peek() { - int r = SSL_peek(Jupiter::SecureSocket::SSLdata_->handle, (char *) this->getBuffer(), this->getBufferSize()-1); - if (r >= 0) ((char *) this->getBuffer())[r] = 0; + if (Jupiter::SecureSocket::SSLdata_->handle == nullptr) + return -1; + Jupiter::Socket::Buffer &buffer = this->getInternalBuffer(); + buffer.erase(); + int r = SSL_peek(Jupiter::SecureSocket::SSLdata_->handle, buffer.get_str(), this->getBufferSize()); + if (r > 0) + buffer.set_length(r); return r; } int Jupiter::SecureSocket::recv() { - if (Jupiter::SecureSocket::SSLdata_->handle == nullptr) return -1; - int r = SSL_read(Jupiter::SecureSocket::SSLdata_->handle, (char *) this->getBuffer(), this->getBufferSize()-1); - if (r >= 0) ((char *) this->getBuffer())[r] = 0; + if (Jupiter::SecureSocket::SSLdata_->handle == nullptr) + return -1; + Jupiter::Socket::Buffer &buffer = this->getInternalBuffer(); + buffer.erase(); + int r = SSL_read(Jupiter::SecureSocket::SSLdata_->handle, buffer.get_str(), this->getBufferSize()); + if (r > 0) + buffer.set_length(r); return r; } diff --git a/Jupiter/Socket.cpp b/Jupiter/Socket.cpp index f4bfa4e..fd4ed03 100644 --- a/Jupiter/Socket.cpp +++ b/Jupiter/Socket.cpp @@ -28,41 +28,46 @@ typedef int SOCKET; #endif // _WIN32 #include "Socket.h" -#include "Functions.h" // makestr() +#include "Functions.h" #include "CString.h" +void Jupiter::Socket::Buffer::set_length(size_t in_length) +{ + this->length = in_length; +} + +char *Jupiter::Socket::Buffer::get_str() const +{ + return this->str; +} + struct Jupiter::Socket::Data { + Jupiter::Socket::Buffer buffer; SOCKET rawSock; unsigned short port; Jupiter::CStringS host; - char *buff; - size_t bufflen; int sockType; int sockProto; #if defined _WIN32 unsigned long blockMode = 0; #endif - Data(char *buffer, size_t bufferSize); + Data(size_t buffer_size); Data(const Data &); - ~Data(); }; -Jupiter::Socket::Data::Data(char *buffer, size_t bufferSize) +Jupiter::Socket::Data::Data(size_t buffer_size) { - Jupiter::Socket::Data::buff = buffer; - Jupiter::Socket::Data::bufflen = bufferSize; + Jupiter::Socket::Data::buffer.setBufferSizeNoCopy(buffer_size); Jupiter::Socket::Data::port = 0; Jupiter::Socket::Data::rawSock = 0; Jupiter::Socket::Data::sockType = SOCK_RAW; Jupiter::Socket::Data::sockProto = IPPROTO_RAW; - for (unsigned int i = 0; i < Jupiter::Socket::Data::bufflen; i++) Jupiter::Socket::Data::buff[i] = 0; } Jupiter::Socket::Data::Data(const Data &source) { - Jupiter::Socket::Data::bufflen = source.bufflen; - Jupiter::Socket::Data::buff = new char[Jupiter::Socket::Data::bufflen]; + Jupiter::Socket::Data::buffer = source.buffer; Jupiter::Socket::Data::port = source.port; Jupiter::Socket::Data::rawSock = source.rawSock; Jupiter::Socket::Data::sockType = source.sockType; @@ -71,12 +76,6 @@ Jupiter::Socket::Data::Data(const Data &source) #if defined _WIN32 Jupiter::Socket::Data::blockMode = source.blockMode; #endif - for (unsigned int i = 0; i < Jupiter::Socket::Data::bufflen; i++) Jupiter::Socket::Data::buff[i] = 0; -} - -Jupiter::Socket::Data::~Data() -{ - if (Jupiter::Socket::Data::buff != nullptr) delete[] Jupiter::Socket::Data::buff; } Jupiter::Socket &Jupiter::Socket::operator=(Jupiter::Socket &&source) @@ -92,7 +91,7 @@ Jupiter::Socket::Socket() : Jupiter::Socket::Socket(4096) Jupiter::Socket::Socket(size_t bufferSize) { - Jupiter::Socket::data_ = new Jupiter::Socket::Data(new char[bufferSize], bufferSize); + Jupiter::Socket::data_ = new Jupiter::Socket::Data(bufferSize); } Jupiter::Socket::Socket(Jupiter::Socket &&source) @@ -101,11 +100,6 @@ Jupiter::Socket::Socket(Jupiter::Socket &&source) source.data_ = nullptr; } -Jupiter::Socket::Socket(char *buffer, size_t bufferSize) -{ - Jupiter::Socket::data_ = new Jupiter::Socket::Data(buffer, bufferSize); -} - Jupiter::Socket::~Socket() { if (Jupiter::Socket::data_ != nullptr) @@ -118,16 +112,6 @@ Jupiter::Socket::~Socket() } } -int Jupiter::Socket::getDescriptor() const -{ - return Jupiter::Socket::data_->rawSock; -} - -void Jupiter::Socket::setDescriptor(int descriptor) -{ - Jupiter::Socket::data_->rawSock = descriptor; -} - void Jupiter::Socket::setType(int type) { Jupiter::Socket::data_->sockType = type; @@ -362,7 +346,7 @@ Jupiter::Socket *Jupiter::Socket::accept() char resolved[NI_MAXHOST]; char resolved_port[NI_MAXSERV]; getnameinfo(&addr, size, resolved, sizeof(resolved), resolved_port, sizeof(resolved_port), NI_NUMERICHOST | NI_NUMERICSERV); - Socket *r = new Socket(Jupiter::Socket::data_->bufflen); + Socket *r = new Socket(Jupiter::Socket::data_->buffer.capacity()); r->data_->rawSock = tSock; r->data_->sockType = Jupiter::Socket::data_->sockType; r->data_->sockProto = Jupiter::Socket::data_->sockProto; @@ -442,35 +426,27 @@ unsigned short Jupiter::Socket::getPort() const return Jupiter::Socket::data_->port; } -const char *Jupiter::Socket::getBuffer() const -{ - return Jupiter::Socket::data_->buff; -} - -void Jupiter::Socket::setBuffer(char *buffer, size_t size) +const Jupiter::ReadableString &Jupiter::Socket::getBuffer() const { - if (Jupiter::Socket::data_->buff != nullptr) delete[] Jupiter::Socket::data_->buff; - Jupiter::Socket::data_->bufflen = size; - Jupiter::Socket::data_->buff = buffer; + return Jupiter::Socket::data_->buffer; } -char *Jupiter::Socket::setBufferSize(size_t size) +size_t Jupiter::Socket::getBufferSize() const { - if (Jupiter::Socket::data_->buff != nullptr) delete[] Jupiter::Socket::data_->buff; - Jupiter::Socket::data_->bufflen = size; - Jupiter::Socket::data_->buff = new char[Jupiter::Socket::data_->bufflen]; - return Jupiter::Socket::data_->buff; + return Jupiter::Socket::data_->buffer.capacity(); } -size_t Jupiter::Socket::getBufferSize() const +const Jupiter::ReadableString &Jupiter::Socket::setBufferSize(size_t size) { - return Jupiter::Socket::data_->bufflen; + Jupiter::Socket::data_->buffer.setBufferSize(size); + return Jupiter::Socket::data_->buffer; } -const char *Jupiter::Socket::getData() +const Jupiter::ReadableString &Jupiter::Socket::getData() { - if (this->recv() > 0) return this->getBuffer(); - return nullptr; + if (this->recv() <= 0) + Jupiter::Socket::data_->buffer.erase(); + return Jupiter::Socket::data_->buffer; } const char *Jupiter::Socket::getLocalHostname() // static @@ -482,7 +458,7 @@ const char *Jupiter::Socket::getLocalHostname() // static void Jupiter::Socket::clearBuffer() { - for (unsigned int i = 0; i < Jupiter::Socket::data_->bufflen; i++) Jupiter::Socket::data_->buff[i] = 0; + Jupiter::Socket::data_->buffer.erase(); } int Jupiter::Socket::send(const char *data, size_t datalen) @@ -510,68 +486,66 @@ int Jupiter::Socket::sendTo(const addrinfo *info, const char *msg) return sendto(Jupiter::Socket::data_->rawSock, msg, strlen(msg), 0, info->ai_addr, info->ai_addrlen); } -int Jupiter::Socket::sendData(const char *data, size_t datalen) -{ - return this->send(data, datalen); -} - -int Jupiter::Socket::sendData(const char *msg) -{ - return this->send(msg); -} - int Jupiter::Socket::peek() { - int r = ::recv(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen - 1, MSG_PEEK); - if (r >= 0) Jupiter::Socket::data_->buff[r] = 0; + Jupiter::Socket::data_->buffer.erase(); + int r = ::recv(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buffer.get_str(), Jupiter::Socket::data_->buffer.capacity(), MSG_PEEK); + if (r > 0) + Jupiter::Socket::data_->buffer.set_length(r); return r; } int Jupiter::Socket::peekFrom(addrinfo *info) { - if (info == nullptr) return recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen - 1, 0, nullptr, nullptr); + Jupiter::Socket::data_->buffer.erase(); + if (info == nullptr) + return recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buffer.get_str(), Jupiter::Socket::data_->buffer.capacity(), MSG_PEEK, nullptr, nullptr); + socklen_t len = info->ai_addrlen; if (len <= 0) { info->ai_addr = new sockaddr(); len = sizeof(sockaddr); } - int r = recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen - 1, MSG_PEEK, info->ai_addr, &len); + int r = recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buffer.get_str(), Jupiter::Socket::data_->buffer.capacity(), MSG_PEEK, info->ai_addr, &len); if (r >= 0) { - Jupiter::Socket::data_->buff[r] = 0; info->ai_addrlen = len; - info->ai_canonname = nullptr; info->ai_family = info->ai_addr->sa_family; - info->ai_flags = 0; - info->ai_next = nullptr; - info->ai_protocol = this->getProtocol(); - info->ai_socktype = this->getType(); + info->ai_protocol = Jupiter::Socket::getProtocol(); + info->ai_socktype = Jupiter::Socket::getType(); } return r; } int Jupiter::Socket::recv() { - int r = ::recv(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen - 1, 0); - if (r >= 0) Jupiter::Socket::data_->buff[r] = 0; + Jupiter::Socket::data_->buffer.erase(); + int r = ::recv(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buffer.get_str(), Jupiter::Socket::data_->buffer.capacity(), 0); + if (r > 0) + Jupiter::Socket::data_->buffer.set_length(r); return r; } int Jupiter::Socket::recvFrom(addrinfo *info) { - if (info == nullptr) return recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen - 1, 0, nullptr, nullptr); - memset(info, 0, sizeof(addrinfo)); - info->ai_addr = new sockaddr(); - socklen_t len = sizeof(sockaddr); - int r = recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buff, Jupiter::Socket::data_->bufflen-1, 0, info->ai_addr, &len); + Jupiter::Socket::data_->buffer.erase(); + if (info == nullptr) + return recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buffer.get_str(), Jupiter::Socket::data_->buffer.capacity(), 0, nullptr, nullptr); + + socklen_t len = info->ai_addrlen; + if (len <= 0) + { + info->ai_addr = new sockaddr(); + len = sizeof(sockaddr); + } + int r = recvfrom(Jupiter::Socket::data_->rawSock, Jupiter::Socket::data_->buffer.get_str(), Jupiter::Socket::data_->buffer.capacity(), 0, info->ai_addr, &len); if (r >= 0) { - Jupiter::Socket::data_->buff[r] = 0; info->ai_addrlen = len; info->ai_family = info->ai_addr->sa_family; - info->ai_protocol = this->getProtocol(); - info->ai_socktype = this->getType(); + info->ai_protocol = Jupiter::Socket::getProtocol(); + info->ai_socktype = Jupiter::Socket::getType(); } return r; } @@ -612,4 +586,19 @@ bool Jupiter::Socket::cleanup() // static WSACleanup(); #endif // _WIN32 return true; +} + +int Jupiter::Socket::getDescriptor() const +{ + return Jupiter::Socket::data_->rawSock; +} + +void Jupiter::Socket::setDescriptor(int descriptor) +{ + Jupiter::Socket::data_->rawSock = descriptor; +} + +Jupiter::Socket::Buffer &Jupiter::Socket::getInternalBuffer() const +{ + return Jupiter::Socket::data_->buffer; } \ No newline at end of file diff --git a/Jupiter/Socket.h b/Jupiter/Socket.h index 958b76f..620f902 100644 --- a/Jupiter/Socket.h +++ b/Jupiter/Socket.h @@ -43,22 +43,6 @@ namespace Jupiter */ class JUPITER_API Socket { - protected: - - /** - * @brief Used by class extensions to get the socket descriptor. - * - * @return A raw socket descriptor. - */ - int getDescriptor() const; - - /** - * @brief Used by class extensions to set the appropriate socket descriptor. - * - * @param descript Socket descriptor. - */ - void setDescriptor(int descript); - public: /** @@ -332,37 +316,29 @@ namespace Jupiter * * @return Buffer. */ - const char *getBuffer() const; + const Jupiter::ReadableString &getBuffer() const; /** - * @brief Assigns a new buffer. + * @brief Returns the size of the socket buffer. * - * @param buffer The new buffer to use. - * @param size The size of the new buffer. + * @return Size of the buffer. */ - void setBuffer(char *buffer, size_t size); + size_t getBufferSize() const; /** - * @brief Creates a new buffer. + * @brief Expands the buffer, if necessary. * * @param size The size of the buffer to be made. * @return The newly created buffer. */ - char *setBufferSize(size_t size); - - /** - * @brief Returns the size of the socket buffer. - * - * @return Size of the buffer. - */ - size_t getBufferSize() const; + const Jupiter::ReadableString &setBufferSize(size_t size); /** * @brief Copies any new socket data to the buffer and returns it. * - * @return Socket buffer if new data is successfully received, nullptr otherwise. + * @return Socket buffer if new data is successfully received, an empty buffer otherwise. */ - const char *getData(); + const Jupiter::ReadableString &getData(); /** * @brief Returns the local hostname of the local machine. @@ -470,9 +446,6 @@ namespace Jupiter */ virtual int sendTo(const addrinfo *info, const char *msg); - int sendData(const char *data, size_t datalen); /** @see send() */ - int sendData(const char *msg); /** @see send() */ - /** * @brief Returns the last error. * On Windows, this currently just calls and returns WSAGetLastError(). @@ -531,17 +504,43 @@ namespace Jupiter Socket(Socket &&source); /** - * @brief Constructor for the Socket class which allows for the use of a pre-existing buffer. + * @brief Destructor for the Socket class. + */ + virtual ~Socket(); + + /** Protected functions and members*/ + protected: + + /** + * @brief An extended verison of the string class, which allows for low-level length and string modification. + */ + class Buffer : public Jupiter::StringL + { + public: + void set_length(size_t in_length); + char *get_str() const; + }; + + /** + * @brief Fetches the buffer where data is stored * - * @param buffer Buffer. - * @param bufferSize Size of the buffer. + * @return Buffer where data is stored */ - Socket(char *buffer, size_t bufferSize); + Buffer &getInternalBuffer() const; /** - * @brief Destructor for the Socket class. + * @brief Used by class extensions to get the socket descriptor. + * + * @return A raw socket descriptor. */ - virtual ~Socket(); + int getDescriptor() const; + + /** + * @brief Used by class extensions to set the appropriate socket descriptor. + * + * @param descript Socket descriptor. + */ + void setDescriptor(int descript); /** Private members */ private: