diff --git a/util/amf.cpp b/util/amf.cpp index b82aceeb..b5f51fad 100644 --- a/util/amf.cpp +++ b/util/amf.cpp @@ -2,6 +2,7 @@ /// Holds all code for the AMF namespace. #include "amf.h" +#include //needed for stderr only /// Returns the std::string Indice for the current object, if available. /// Returns an empty string if no indice exists. diff --git a/util/ddv_socket.cpp b/util/ddv_socket.cpp deleted file mode 100644 index 72ed286e..00000000 --- a/util/ddv_socket.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/// \file ddv_socket.cpp -/// Holds all code for the DDV namespace. - -#include "ddv_socket.h" - -/// Create a new base socket. This is a basic constructor for converting any valid socket to a DDV::Socket. -/// \param sockNo Integer representing the socket to convert. -DDV::Socket::Socket(int sockNo){ - sock = sockNo; - Error = false; - Blocking = false; -}//DDV::Socket basic constructor - -/// Create a new disconnected base socket. This is a basic constructor for placeholder purposes. -/// A socket created like this is always disconnected and should/could be overwritten at some point. -DDV::Socket::Socket(){ - sock = -1; - Error = false; - Blocking = false; -}//DDV::Socket basic constructor - -/// Close connection. The internal socket is closed and then set to -1. -void DDV::Socket::close(){ - #if DEBUG >= 3 - fprintf(stderr, "Socket closed.\n"); - #endif - ::close(sock); - sock = -1; -}//DDV::Socket::close - -/// Returns internal socket number. -int DDV::Socket::getSocket(){return sock;} - -/// Create a new Unix Socket. This socket will (try to) connect to the given address right away. -/// \param address String containing the location of the Unix socket to connect to. -/// \param nonblock Whether the socket should be nonblocking. False by default. -DDV::Socket::Socket(std::string address, bool nonblock){ - sock = socket(PF_UNIX, SOCK_STREAM, 0); - if (sock < 0){ - #if DEBUG >= 1 - fprintf(stderr, "Could not create socket! Error: %s\n", strerror(errno)); - #endif - return; - } - Error = false; - Blocking = false; - sockaddr_un addr; - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, address.c_str(), address.size()+1); - int r = connect(sock, (sockaddr*)&addr, sizeof(addr)); - if (r == 0){ - if (nonblock){ - int flags = fcntl(sock, F_GETFL, 0); - flags |= O_NONBLOCK; - fcntl(sock, F_SETFL, flags); - } - }else{ - #if DEBUG >= 1 - fprintf(stderr, "Could not connect to %s! Error: %s\n", address.c_str(), strerror(errno)); - #endif - close(); - } -}//DDV::Socket Unix Contructor - -/// Returns the ready-state for this socket. -/// \returns 1 if data is waiting to be read, -1 if not connected, 0 otherwise. -signed int DDV::Socket::ready(){ - if (sock < 0) return -1; - char tmp; - int preflags = fcntl(sock, F_GETFL, 0); - int postflags = preflags | O_NONBLOCK; - fcntl(sock, F_SETFL, postflags); - int r = recv(sock, &tmp, 1, MSG_PEEK); - fcntl(sock, F_SETFL, preflags); - if (r < 0){ - if (errno == EAGAIN || errno == EWOULDBLOCK){ - return 0; - }else{ - #if DEBUG >= 2 - fprintf(stderr, "Socket ready error! Error: %s\n", strerror(errno)); - #endif - close(); - return -1; - } - } - if (r == 0){ - close(); return -1; - } - return r; -} - -/// Returns the connected-state for this socket. -/// Note that this function might be slightly behind the real situation. -/// The connection status is updated after every read/write attempt, when errors occur -/// and when the socket is closed manually. -/// \returns True if socket is connected, false otherwise. -bool DDV::Socket::connected(){ - return (sock >= 0); -} - -/// Writes data to socket. This function blocks if the socket is blocking and all data cannot be written right away. -/// If the socket is nonblocking and not all data can be written, this function sets internal variable Blocking to true -/// and returns false. -/// \param buffer Location of the buffer to write from. -/// \param len Amount of bytes to write. -/// \returns True if the whole write was succesfull, false otherwise. -bool DDV::Socket::write(const void * buffer, int len){ - int sofar = 0; - if (sock < 0){return false;} - while (sofar != len){ - int r = send(sock, (char*)buffer + sofar, len-sofar, 0); - if (r <= 0){ - Error = true; - #if DEBUG >= 2 - fprintf(stderr, "Could not write data! Error: %s\n", strerror(errno)); - #endif - close(); - return false; - }else{ - sofar += r; - } - } - return true; -}//DDv::Socket::write - - -/// Reads data from socket. This function blocks if the socket is blocking and all data cannot be read right away. -/// If the socket is nonblocking and not all data can be read, this function sets internal variable Blocking to true -/// and returns false. -/// \param buffer Location of the buffer to read to. -/// \param len Amount of bytes to read. -/// \returns True if the whole read was succesfull, false otherwise. -bool DDV::Socket::read(void * buffer, int len){ - int sofar = 0; - if (sock < 0){return false;} - while (sofar != len){ - int r = recv(sock, (char*)buffer + sofar, len-sofar, 0); - if (r <= 0){ - Error = true; - #if DEBUG >= 2 - fprintf(stderr, "Could not read data! Error: %s\n", strerror(errno)); - #endif - close(); - return false; - }else{ - sofar += r; - } - } - return true; -}//DDV::Socket::read - -/// Read call that is compatible with file access syntax. This function simply calls the other read function. -bool DDV::Socket::read(void * buffer, int width, int count){return read(buffer, width*count);} -/// Write call that is compatible with file access syntax. This function simply calls the other write function. -bool DDV::Socket::write(void * buffer, int width, int count){return write(buffer, width*count);} -/// Write call that is compatible with std::string. This function simply calls the other write function. -bool DDV::Socket::write(const std::string data){return write(data.c_str(), data.size());} - -/// Incremental write call. This function tries to write len bytes to the socket from the buffer, -/// returning the amount of bytes it actually wrote. -/// \param buffer Location of the buffer to write from. -/// \param len Amount of bytes to write. -/// \returns The amount of bytes actually written. -int DDV::Socket::iwrite(void * buffer, int len){ - int r = send(sock, buffer, len, 0); - if (r < 0){ - switch (errno){ - case EWOULDBLOCK: return 0; break; - default: - Error = true; - #if DEBUG >= 2 - fprintf(stderr, "Could not iwrite data! Error: %s\n", strerror(errno)); - #endif - close(); - return 0; - break; - } - } - if (r == 0){close();} - return r; -}//DDV::Socket::iwrite - -/// Incremental read call. This function tries to read len bytes to the buffer from the socket, -/// returning the amount of bytes it actually read. -/// \param buffer Location of the buffer to read to. -/// \param len Amount of bytes to read. -/// \returns The amount of bytes actually read. -int DDV::Socket::iread(void * buffer, int len){ - int r = recv(sock, buffer, len, 0); - if (r < 0){ - switch (errno){ - case EWOULDBLOCK: return 0; break; - default: - Error = true; - #if DEBUG >= 2 - fprintf(stderr, "Could not iread data! Error: %s\n", strerror(errno)); - #endif - close(); - return 0; - break; - } - } - if (r == 0){close();} - return r; -}//DDV::Socket::iread - -/// Read call that is compatible with std::string. -/// Data is read using iread (which is nonblocking if the DDV::Socket itself is), -/// then appended to end of buffer. -/// \param buffer std::string to append data to. -/// \return True if new data arrived, false otherwise. -bool DDV::Socket::read(std::string & buffer){ - char cbuffer[5000]; - if (!read(cbuffer, 1)){return false;} - int num = iread(cbuffer+1, 4999); - if (num > 0){ - buffer.append(cbuffer, num+1); - }else{ - buffer.append(cbuffer, 1); - } - return true; -}//read - -/// Create a new base ServerSocket. The socket is never connected, and a placeholder for later connections. -DDV::ServerSocket::ServerSocket(){ - sock = -1; -}//DDV::ServerSocket base Constructor - -/// Create a new TCP ServerSocket. The socket is immediately bound and set to listen. -/// A maximum of 100 connections will be accepted between accept() calls. -/// Any further connections coming in will be dropped. -/// \param port The TCP port to listen on -/// \param hostname (optional) The interface to bind to. The default is 0.0.0.0 (all interfaces). -/// \param nonblock (optional) Whether accept() calls will be nonblocking. Default is false (blocking). -DDV::ServerSocket::ServerSocket(int port, std::string hostname, bool nonblock){ - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0){ - #if DEBUG >= 1 - fprintf(stderr, "Could not create socket! Error: %s\n", strerror(errno)); - #endif - return; - } - int on = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); - if (nonblock){ - int flags = fcntl(sock, F_GETFL, 0); - flags |= O_NONBLOCK; - fcntl(sock, F_SETFL, flags); - } - struct sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_port = htons(port);//set port - inet_pton(AF_INET, hostname.c_str(), &addr.sin_addr);//set interface, 0.0.0.0 (default) is all - int ret = bind(sock, (sockaddr*)&addr, sizeof(addr));//do the actual bind - if (ret == 0){ - ret = listen(sock, 100);//start listening, backlog of 100 allowed - if (ret == 0){ - return; - }else{ - #if DEBUG >= 1 - fprintf(stderr, "Listen failed! Error: %s\n", strerror(errno)); - #endif - close(); - return; - } - }else{ - #if DEBUG >= 1 - fprintf(stderr, "Binding failed! Error: %s\n", strerror(errno)); - #endif - close(); - return; - } -}//DDV::ServerSocket TCP Constructor - -/// Create a new Unix ServerSocket. The socket is immediately bound and set to listen. -/// A maximum of 100 connections will be accepted between accept() calls. -/// Any further connections coming in will be dropped. -/// The address used will first be unlinked - so it succeeds if the Unix socket already existed. Watch out for this behaviour - it will delete any file located at address! -/// \param address The location of the Unix socket to bind to. -/// \param nonblock (optional) Whether accept() calls will be nonblocking. Default is false (blocking). -DDV::ServerSocket::ServerSocket(std::string address, bool nonblock){ - unlink(address.c_str()); - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0){ - #if DEBUG >= 1 - fprintf(stderr, "Could not create socket! Error: %s\n", strerror(errno)); - #endif - return; - } - if (nonblock){ - int flags = fcntl(sock, F_GETFL, 0); - flags |= O_NONBLOCK; - fcntl(sock, F_SETFL, flags); - } - sockaddr_un addr; - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, address.c_str(), address.size()+1); - int ret = bind(sock, (sockaddr*)&addr, sizeof(addr)); - if (ret == 0){ - ret = listen(sock, 100);//start listening, backlog of 100 allowed - if (ret == 0){ - return; - }else{ - #if DEBUG >= 1 - fprintf(stderr, "Listen failed! Error: %s\n", strerror(errno)); - #endif - close(); - return; - } - }else{ - #if DEBUG >= 1 - fprintf(stderr, "Binding failed! Error: %s\n", strerror(errno)); - #endif - close(); - return; - } -}//DDV::ServerSocket Unix Constructor - -/// Accept any waiting connections. If the DDV::ServerSocket is blocking, this function will block until there is an incoming connection. -/// If the DDV::ServerSocket is nonblocking, it might return a DDV::Socket that is not connected, so check for this. -/// \param nonblock (optional) Whether the newly connected socket should be nonblocking. Default is false (blocking). -/// \returns A DDV::Socket, which may or may not be connected, depending on settings and circumstances. -DDV::Socket DDV::ServerSocket::accept(bool nonblock){ - if (sock < 0){return DDV::Socket(-1);} - int r = ::accept(sock, 0, 0); - //set the socket to be nonblocking, if requested. - //we could do this through accept4 with a flag, but that call is non-standard... - if ((r >= 0) && nonblock){ - int flags = fcntl(r, F_GETFL, 0); - flags |= O_NONBLOCK; - fcntl(r, F_SETFL, flags); - } - if (r < 0){ - if (errno != EWOULDBLOCK && errno != EAGAIN){close();} - } - return DDV::Socket(r); -} - -/// Close connection. The internal socket is closed and then set to -1. -void DDV::ServerSocket::close(){ - ::close(sock); - sock = -1; -}//DDV::ServerSocket::close - -/// Returns the connected-state for this socket. -/// Note that this function might be slightly behind the real situation. -/// The connection status is updated after every accept attempt, when errors occur -/// and when the socket is closed manually. -/// \returns True if socket is connected, false otherwise. -bool DDV::ServerSocket::connected(){ - return (sock >= 0); -}//DDV::ServerSocket::connected - -/// Returns internal socket number. -int DDV::ServerSocket::getSocket(){return sock;} diff --git a/util/ddv_socket.h b/util/ddv_socket.h deleted file mode 100644 index 5d58e0bd..00000000 --- a/util/ddv_socket.h +++ /dev/null @@ -1,58 +0,0 @@ -/// \file ddv_socket.h -/// Holds all headers for the DDV namespace. - -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -///Holds DDV Socket tools. -namespace DDV{ - - /// This class is for easy communicating through sockets, either TCP or Unix. - class Socket{ - private: - int sock; ///< Internally saved socket number. - public: - Socket(); ///< Create a new disconnected base socket. - Socket(int sockNo); ///< Create a new base socket. - Socket(std::string adres, bool nonblock = false); ///< Create a new Unix Socket. - bool Error; ///< Set to true if a socket error happened. - bool Blocking; ///< Set to true if a socket is currently or wants to be blocking. - signed int ready(); ///< Returns the ready-state for this socket. - bool connected(); ///< Returns the connected-state for this socket. - bool read(void * buffer, int len); ///< Reads data from socket. - bool read(void * buffer, int width, int count); ///< Read call that is compatible with file access syntax. - bool write(const void * buffer, int len); ///< Writes data to socket. - bool write(void * buffer, int width, int count); ///< Write call that is compatible with file access syntax. - bool write(const std::string data); ///< Write call that is compatible with std::string. - int iwrite(void * buffer, int len); ///< Incremental write call. - int iread(void * buffer, int len); ///< Incremental read call. - bool read(std::string & buffer); ///< Read call that is compatible with std::string. - void close(); ///< Close connection. - int getSocket(); ///< Returns internal socket number. - }; - - /// This class is for easily setting up listening socket, either TCP or Unix. - class ServerSocket{ - private: - int sock; ///< Internally saved socket number. - public: - ServerSocket(); ///< Create a new base ServerSocket. - ServerSocket(int port, std::string hostname = "0.0.0.0", bool nonblock = false); ///< Create a new TCP ServerSocket. - ServerSocket(std::string adres, bool nonblock = false); ///< Create a new Unix ServerSocket. - Socket accept(bool nonblock = false); ///< Accept any waiting connections. - bool connected(); ///< Returns the connected-state for this socket. - void close(); ///< Close connection. - int getSocket(); ///< Returns internal socket number. - }; - -}; diff --git a/util/flv_tag.cpp b/util/flv_tag.cpp index 02494b56..140183f3 100644 --- a/util/flv_tag.cpp +++ b/util/flv_tag.cpp @@ -7,7 +7,6 @@ #include //for Tag::FileLoader #include //malloc #include //memcpy -#include "ddv_socket.h" //socket functions char FLV::Header[13]; ///< Holds the last FLV header parsed. bool FLV::Parse_Error = false; ///< This variable is set to true if a problem is encountered while parsing the FLV. @@ -261,7 +260,7 @@ bool FLV::Tag::MemLoader(char * D, unsigned int S, unsigned int & P){ /// \param sofar Current amount read. /// \param sock Socket to read from. /// \return True if count bytes are read succesfully, false otherwise. -bool FLV::Tag::SockReadUntil(char * buffer, unsigned int count, unsigned int & sofar, DDV::Socket & sock){ +bool FLV::Tag::SockReadUntil(char * buffer, unsigned int count, unsigned int & sofar, Socket::Connection & sock){ if (sofar == count){return true;} if (!sock.read(buffer + sofar,count-sofar)){ if (errno != EWOULDBLOCK){ @@ -284,7 +283,7 @@ bool FLV::Tag::SockReadUntil(char * buffer, unsigned int count, unsigned int & s /// While this function returns false, the Tag might not contain valid data. /// \param sock The socket to read from. /// \return True if a whole tag is succesfully read, false otherwise. -bool FLV::Tag::SockLoader(DDV::Socket sock){ +bool FLV::Tag::SockLoader(Socket::Connection sock){ if (buf < 15){data = (char*)realloc(data, 15); buf = 15;} if (done){ if (SockReadUntil(data, 11, sofar, sock)){ @@ -325,7 +324,7 @@ bool FLV::Tag::SockLoader(DDV::Socket sock){ /// \param sock The socket to read from. /// \return True if a whole tag is succesfully read, false otherwise. bool FLV::Tag::SockLoader(int sock){ - return SockLoader(DDV::Socket(sock)); + return SockLoader(Socket::Connection(sock)); }//Tag::SockLoader /// Helper function for FLV::FileLoader. diff --git a/util/flv_tag.h b/util/flv_tag.h index 0ba13ea5..74d0ffa7 100644 --- a/util/flv_tag.h +++ b/util/flv_tag.h @@ -2,7 +2,7 @@ /// Holds all headers for the FLV namespace. #pragma once -#include "ddv_socket.h" +#include "socket.h" #include /// This namespace holds all FLV-parsing related functionality. @@ -31,7 +31,7 @@ namespace FLV { //loader functions bool MemLoader(char * D, unsigned int S, unsigned int & P); bool SockLoader(int sock); - bool SockLoader(DDV::Socket sock); + bool SockLoader(Socket::Connection sock); bool FileLoader(FILE * f); protected: int buf; ///< Maximum length of buffer space. @@ -39,7 +39,7 @@ namespace FLV { unsigned int sofar; ///< How many bytes are read sofar? //loader helper functions bool MemReadUntil(char * buffer, unsigned int count, unsigned int & sofar, char * D, unsigned int S, unsigned int & P); - bool SockReadUntil(char * buffer, unsigned int count, unsigned int & sofar, DDV::Socket & sock); + bool SockReadUntil(char * buffer, unsigned int count, unsigned int & sofar, Socket::Connection & sock); bool FileReadUntil(char * buffer, unsigned int count, unsigned int & sofar, FILE * f); };//Tag diff --git a/util/http_parser.cpp b/util/http_parser.cpp index 4fe7b94f..ec648a39 100644 --- a/util/http_parser.cpp +++ b/util/http_parser.cpp @@ -127,11 +127,11 @@ void HTTP::Parser::SetVar(std::string i, std::string v){ vars[i] = v; } -/// Attempt to read a whole HTTP request or response from DDV::Socket sock. +/// Attempt to read a whole HTTP request or response from Socket::Connection. /// \param sock The socket to use. /// \param nonblock When true, will not block even if the socket is blocking. /// \return True of a whole request or response was read, false otherwise. -bool HTTP::Parser::Read(DDV::Socket & sock, bool nonblock){ +bool HTTP::Parser::Read(Socket::Connection & sock, bool nonblock){ if (nonblock && (sock.ready() < 1)){return parse();} sock.read(HTTPbuffer); return parse(); @@ -206,20 +206,20 @@ bool HTTP::Parser::parse(){ /// Sends data as response to conn. /// The response is automatically first build using HTTP::Parser::BuildResponse(). -/// \param conn The DDV::Socket to send the response over. +/// \param conn The Socket::Connection to send the response over. /// \param code The HTTP response code. Usually you want 200. /// \param message The HTTP response message. Usually you want "OK". -void HTTP::Parser::SendResponse(DDV::Socket & conn, std::string code, std::string message){ +void HTTP::Parser::SendResponse(Socket::Connection & conn, std::string code, std::string message){ std::string tmp = BuildResponse(code, message); conn.write(tmp); } /// Sends data as HTTP/1.1 bodypart to conn. /// HTTP/1.1 chunked encoding is automatically applied if needed. -/// \param conn The DDV::Socket to send the part over. +/// \param conn The Socket::Connection to send the part over. /// \param buffer The buffer to send. /// \param len The length of the buffer. -void HTTP::Parser::SendBodyPart(DDV::Socket & conn, char * buffer, int len){ +void HTTP::Parser::SendBodyPart(Socket::Connection & conn, char * buffer, int len){ std::string tmp; tmp.append(buffer, len); SendBodyPart(conn, tmp); @@ -227,9 +227,9 @@ void HTTP::Parser::SendBodyPart(DDV::Socket & conn, char * buffer, int len){ /// Sends data as HTTP/1.1 bodypart to conn. /// HTTP/1.1 chunked encoding is automatically applied if needed. -/// \param conn The DDV::Socket to send the part over. +/// \param conn The Socket::Connection to send the part over. /// \param bodypart The data to send. -void HTTP::Parser::SendBodyPart(DDV::Socket & conn, std::string bodypart){ +void HTTP::Parser::SendBodyPart(Socket::Connection & conn, std::string bodypart){ if (protocol == "HTTP/1.1"){ static char len[10]; int sizelen; diff --git a/util/http_parser.h b/util/http_parser.h index ed8f64fe..d7048eae 100644 --- a/util/http_parser.h +++ b/util/http_parser.h @@ -6,7 +6,7 @@ #include #include #include -#include "ddv_socket.h" +#include "socket.h" /// Holds all HTTP processing related code. namespace HTTP{ @@ -14,7 +14,7 @@ namespace HTTP{ class Parser{ public: Parser(); - bool Read(DDV::Socket & sock, bool nonblock = true); + bool Read(Socket::Connection & sock, bool nonblock = true); bool Read(FILE * F); std::string GetHeader(std::string i); std::string GetVar(std::string i); @@ -25,9 +25,9 @@ namespace HTTP{ void SetBody(char * buffer, int len); std::string BuildRequest(); std::string BuildResponse(std::string code, std::string message); - void SendResponse(DDV::Socket & conn, std::string code, std::string message); - void SendBodyPart(DDV::Socket & conn, char * buffer, int len); - void SendBodyPart(DDV::Socket & conn, std::string bodypart); + void SendResponse(Socket::Connection & conn, std::string code, std::string message); + void SendBodyPart(Socket::Connection & conn, char * buffer, int len); + void SendBodyPart(Socket::Connection & conn, std::string bodypart); void Clean(); bool CleanForNext(); std::string body; diff --git a/util/server_setup.cpp b/util/server_setup.cpp index 36e09c47..20d8c4f5 100644 --- a/util/server_setup.cpp +++ b/util/server_setup.cpp @@ -21,14 +21,14 @@ #error "No configuration file section was set!" #endif -#include "ddv_socket.h" //DDVTech Socket wrapper +#include "socket.h" //Socket library #include #include #include #include #define defstr(x) #x ///< converts a define name to string #define defstrh(x) "[" defstr(x) "]" ///< converts define name to [string] -DDV::ServerSocket server_socket(-1); ///< Placeholder for the server socket +Socket::Server server_socket(-1); ///< Placeholder for the server socket /// Basic signal handler. Disconnects the server_socket if it receives /// a SIGINT, SIGHUP or SIGTERM signal, but does nothing for SIGPIPE. @@ -53,7 +53,7 @@ void signal_handler (int signum){ /// The default port is set by define #DEFAULT_PORT. /// The configuration file section is set by define #CONFIGSECT. int main(int argc, char ** argv){ - DDV::Socket S;//placeholder for incoming connections + Socket::Connection S;//placeholder for incoming connections //setup signal handler struct sigaction new_action; @@ -135,7 +135,7 @@ int main(int argc, char ** argv){ }//configuration //setup a new server socket, for the correct interface and port - server_socket = DDV::ServerSocket(listen_port, interface); + server_socket = Socket::Server(listen_port, interface); #if DEBUG >= 3 fprintf(stderr, "Made a listening socket on %s:%i...\n", interface.c_str(), listen_port); #endif