This class represent an abstract socket connection (udp | tcp server | tcp client). More...
#include <socket.hh>
Public Member Functions | |||||||
Socket (SOCKET_KIND kind, SOCKET_VERSION version=V4) | |||||||
Socket (SOCKET_KIND kind, PROTO_KIND pkind, SOCKET_VERSION version=V4) | |||||||
virtual | ~Socket () | ||||||
void | write (const std::string &str) | ||||||
function used by << operator (write a string on current socket) | |||||||
bool | connected () const | ||||||
return true when socket is connected | |||||||
int | get_socket () | ||||||
get socket (fd) warning: be very carefull with this method | |||||||
void | add_delim (const std::string &delim) | ||||||
set the delimitor for the text mode | |||||||
void | del_delim (const std::string &delim) | ||||||
delete this delimitor for the socket | |||||||
void | allow_empty_lines () | ||||||
, if set, empty lines will be returned in text procols (if not, they are skipped) | |||||||
void | init_tls (GnuTLSKind kind, unsigned size=1024, const std::string &certfile="", const std::string &keyfile="", const std::string &trustfile="", const std::string &crlfile="") | ||||||
| |||||||
void | enable_tls () | ||||||
Enable TLS on socket. | |||||||
virtual std::string | read ()=0 | ||||||
function used by >> operator (read a string on current socket) | |||||||
virtual std::string | read (int timeout)=0 | ||||||
read a string with a timeout | |||||||
virtual std::string | readn (unsigned int size)=0 | ||||||
read a string from socket | |||||||
virtual std::string | readn (int timeout, unsigned int size)=0 | ||||||
read a string with a timeout | |||||||
Protected Member Functions | |||||||
void | _close (int socket) const | ||||||
Close a connnection
| |||||||
void | _listen (int socket) const | ||||||
Listen on port
| |||||||
virtual std::string | _read_line (int socket)=0 | ||||||
Get a line from socket (when used with textual protocol)
| |||||||
virtual std::string | _read_line_bin (int socket, unsigned int size)=0 | ||||||
Get a line from socket (when used with binary protocol)
| |||||||
void | _write_str (int socket, const std::string &str) const | ||||||
Write a string to a socket (when used with textual protocol)
| |||||||
void | _write_str_bin (int socket, const std::string &str) const | ||||||
Write a string to a socket (when used with binary protocol)
| |||||||
void | _set_timeout (bool enable, int socket, int timeout) | ||||||
set a timeout on a socket | |||||||
std::pair< int, int > | _find_delim (const std::string &str, int start) const | ||||||
bool | _update_buffer (std::pair< int, int > &delim, int &i, std::string &str) | ||||||
look delimiter and remove delimiter at begining of buffer if needed | |||||||
bool | _check_answer (int res, std::string &str) | ||||||
return the content of the buffer is there is | |||||||
Protected Attributes | |||||||
SOCKET_KIND | _kind | ||||||
SOCKET_VERSION | _version | ||||||
unsigned | _state_timeout | ||||||
int | _socket | ||||||
int | _recv_flags | ||||||
struct sockaddr_in | _addr | ||||||
PROTO_KIND | _proto_kind | ||||||
std::list< std::string > | _delim | ||||||
bool | _empty_lines | ||||||
std::string | _buffer | ||||||
bool | _tls |
This class represent an abstract socket connection (udp | tcp server | tcp client).
Definition at line 100 of file socket.hh.
Network::Socket::Socket | ( | SOCKET_KIND | kind, | |
SOCKET_VERSION | version = V4 | |||
) |
Definition at line 31 of file socket.cc.
References _delim, HERE, and Network::V6.
00032 : 00033 _kind(kind), _version(version), _state_timeout(0), 00034 _socket(0), _recv_flags(kind), _proto_kind(text), _empty_lines(false), 00035 _buffer(""), _tls(false) 00036 { 00037 _delim.push_back("\0"); 00038 #ifdef LIBSOCKET_WIN 00039 WSADATA wsadata; 00040 if (WSAStartup(MAKEWORD(1, 1), &wsadata) != 0) 00041 throw WSAStartupError("WSAStartup failed", HERE); 00042 #endif 00043 #ifndef IPV6_ENABLED 00044 if (version == V6) 00045 throw Ipv6SupportError("lib was not compiled with ipv6 support", HERE); 00046 #endif }
Network::Socket::Socket | ( | SOCKET_KIND | kind, | |
PROTO_KIND | pkind, | |||
SOCKET_VERSION | version = V4 | |||
) |
Definition at line 48 of file socket.cc.
References _delim, HERE, and Network::V6.
00049 : 00050 _kind(kind), _version(version), _state_timeout(0), 00051 _socket(0), _recv_flags(kind), _proto_kind(pkind), _empty_lines(false), 00052 _buffer(""), _tls(false) 00053 { 00054 _delim.push_back("\0"); 00055 #ifdef LIBSOCKET_WIN 00056 WSADATA wsadata; 00057 if (WSAStartup(MAKEWORD(1, 1), &wsadata) != 0) 00058 throw WSAStartupError("WSAStartup failed", HERE); 00059 #endif 00060 #ifndef IPV6_ENABLED 00061 if (version == V6) 00062 throw Ipv6SupportError("lib was not compiled with ipv6 support", HERE); 00063 #endif }
bool Network::Socket::_check_answer | ( | int | res, | |
std::string & | str | |||
) | [inline, protected] |
return the content of the buffer is there is
Definition at line 28 of file socket.hxx.
References _buffer, _state_timeout, and HERE.
00029 { 00030 if (res <= 0) 00031 { 00032 if (!_buffer.size()) // No more data... 00033 throw ConnectionClosed("Connection Closed", HERE); 00034 else 00035 { 00036 str += _buffer; 00037 _buffer = ""; 00038 _state_timeout = 0; 00039 return true; 00040 } 00041 } 00042 return false; 00043 }
void Network::Socket::_close | ( | int | socket | ) | const [protected] |
Close a connnection
CloseException | when close libc function return a negative value. |
Definition at line 167 of file socket.cc.
00168 { 00169 #ifndef LIBSOCKET_WIN 00170 if (socket < 0 || close(socket) < 0) 00171 throw CloseError("Close Error", HERE); 00172 socket = 0; 00173 #else 00174 if (socket < 0 || closesocket(socket) < 0) 00175 throw CloseError("Close Error", HERE); 00176 socket = 0; 00177 #endif 00178 #ifdef TLS 00179 if (_tls) 00180 { 00181 std::cout << "Deletion..." << std::endl; 00182 gnutls_deinit(_session); 00183 if (_tls_main) 00184 { 00185 gnutls_certificate_free_credentials(_x509_cred); 00186 gnutls_global_deinit(); 00187 } 00188 } 00189 #endif 00190 }
std::pair< int, int > Network::Socket::_find_delim | ( | const std::string & | str, | |
int | start | |||
) | const [protected] |
Definition at line 339 of file socket.cc.
References _delim.
Referenced by _update_buffer().
00340 { 00341 int i = -1; 00342 int pos = -1, size = 0; 00343 std::list<std::string>::const_iterator it; 00344 00345 // Looking for the first delimiter. 00346 if (_delim.size() > 0) 00347 { 00348 it = _delim.begin(); 00349 while (it != _delim.end()) 00350 { 00351 if (*it == "") 00352 i = str.find('\0', start); 00353 else 00354 i = str.find(*it, start); 00355 if ((i >= 0) && ((unsigned int)i < str.size()) && 00356 (pos < 0 || i < pos)) 00357 { 00358 pos = i; 00359 size = it->size() ? it->size() : 1; 00360 } 00361 it++; 00362 } 00363 } 00364 return std::pair<int, int>(pos, size); 00365 }
void Network::Socket::_listen | ( | int | socket | ) | const [protected] |
virtual std::string Network::Socket::_read_line | ( | int | socket | ) | [protected, pure virtual] |
Get a line from socket (when used with textual protocol)
NoConnection | when there is no open socket | |
ConnectionClosed | when there is no more connection. |
Implemented in Network::LocalSocket, and Network::NetSocket.
virtual std::string Network::Socket::_read_line_bin | ( | int | socket, | |
unsigned int | size | |||
) | [protected, pure virtual] |
Get a line from socket (when used with binary protocol)
NoConnection | when there is no open socket | |
ConnectionClosed | when there is no more connection. |
Implemented in Network::LocalSocket, Network::NetSocket, Network::TcpSocket, and Network::UdpSocket.
void Network::Socket::_set_timeout | ( | bool | enable, | |
int | socket, | |||
int | timeout | |||
) | [protected] |
set a timeout on a socket
timeout | is in second |
Timeout | when there is a timeout | |
SelectError | when select libc function return a negative value |
Definition at line 272 of file socket.cc.
References HERE.
00273 { 00274 fd_set fdset; 00275 struct timeval timetowait; 00276 int res; 00277 00278 if (enable) 00279 timetowait.tv_sec = timeout; 00280 else 00281 timetowait.tv_sec = 65535; 00282 timetowait.tv_usec = 0; 00283 FD_ZERO(&fdset); 00284 FD_SET(socket, &fdset); 00285 if (enable) 00286 res = select(socket + 1, &fdset, NULL, NULL, &timetowait); 00287 else 00288 res = select(socket + 1, &fdset, NULL, NULL, NULL); 00289 if (res < 0) 00290 throw SelectError("Select error", HERE); 00291 if (res == 0) 00292 throw Timeout("Timeout on socket", HERE); 00293 }
bool Network::Socket::_update_buffer | ( | std::pair< int, int > & | delim, | |
int & | i, | |||
std::string & | str | |||
) | [inline, protected] |
look delimiter and remove delimiter at begining of buffer if needed
Definition at line 45 of file socket.hxx.
References _buffer, _empty_lines, and _find_delim().
00047 { 00048 delim = _find_delim(_buffer, 0); 00049 i = delim.first; 00050 while (!_empty_lines && !i) 00051 { 00052 // remove delimiter in front of buffer 00053 _buffer = _buffer.substr(delim.second, _buffer.size() - delim.second); 00054 delim = _find_delim(_buffer, 0); 00055 i = delim.first; 00056 } 00057 if ((i > 0 || _empty_lines) && ((unsigned int)i < _buffer.size())) 00058 { 00059 str = _buffer.substr(0, i); 00060 _buffer = _buffer.substr(i + delim.second, 00061 _buffer.size() - i - delim.second); 00062 return true; 00063 } 00064 else 00065 return false; 00066 }
void Network::Socket::_write_str | ( | int | socket, | |
const std::string & | str | |||
) | const [protected] |
Write a string to a socket (when used with textual protocol)
NoConnection | when there is no open socket | |
ConnectionClosed | when there is no more connection. |
Definition at line 198 of file socket.cc.
References _addr, _tls, _version, HERE, SENDTO_FLAGS, and Network::V4.
Referenced by write().
00199 { 00200 int res = 1; 00201 unsigned int count = 0; 00202 const char *buf; 00203 00204 buf = str.c_str(); 00205 if (socket < 0) 00206 throw NoConnection("No Socket", HERE); 00207 while (res && count < str.size()) 00208 { 00209 #ifdef IPV6_ENABLED 00210 if (V4 == _version) 00211 #endif 00212 #ifdef TLS 00213 if (_tls) 00214 res = gnutls_record_send(_session, buf + count, str.size() - count); 00215 else 00216 #endif 00217 res = sendto(socket, buf + count, str.size() - count, SENDTO_FLAGS, 00218 (const struct sockaddr*)&_addr, sizeof(_addr)); 00219 #ifdef IPV6_ENABLED 00220 else 00221 res = sendto(socket, buf + count, str.size() - count, SENDTO_FLAGS, 00222 (const struct sockaddr*)&_addr6, sizeof(_addr6)); 00223 #endif 00224 if (res <= 0) 00225 throw ConnectionClosed("Connection Closed", HERE); 00226 count += res; 00227 } 00228 }
void Network::Socket::_write_str_bin | ( | int | socket, | |
const std::string & | str | |||
) | const [protected] |
Write a string to a socket (when used with binary protocol)
NoConnection | when there is no open socket | |
ConnectionClosed | when there is no more connection. |
Definition at line 230 of file socket.cc.
References _addr, _tls, _version, HERE, SENDTO_FLAGS, and Network::V4.
Referenced by write().
00231 { 00232 int res = 1; 00233 unsigned int count = 0; 00234 #ifdef LIBSOCKET_WIN 00235 char* buf = new char[str.size() + 2]; 00236 #else 00237 char buf[str.size() + 2]; 00238 #endif 00239 buf[0] = str.size() / 256; 00240 buf[1] = str.size() % 256; 00241 memcpy(buf + 2, str.c_str(), str.size()); 00242 if (socket < 0) 00243 throw NoConnection("No Socket", HERE); 00244 while (res && count < str.size() + 2) 00245 { 00246 #ifdef IPV6_ENABLED 00247 if (V4 == _version) 00248 #endif 00249 #ifdef TLS 00250 if (_tls) 00251 res = gnutls_record_send(_session, buf + count, str.size() + 2 - count); 00252 else 00253 #endif 00254 res = sendto(socket, buf + count, str.size() + 2 - count, 00255 SENDTO_FLAGS, 00256 (const struct sockaddr*)&_addr, sizeof(_addr)); 00257 #ifdef IPV6_ENABLED 00258 else 00259 res = sendto(socket, buf + count, str.size() + 2 - count, 00260 \ SENDTO_FLAGS, 00261 (const struct sockaddr*)&_addr6, sizeof(_addr6)); 00262 #endif 00263 if (res <= 0) 00264 throw ConnectionClosed("Connection Closed", HERE); 00265 count += res; 00266 } 00267 #ifdef LIBSOCKET_WIN 00268 delete[] buf; 00269 #endif 00270 }
void Network::Socket::add_delim | ( | const std::string & | delim | ) |
void Network::Socket::allow_empty_lines | ( | ) |
, if set, empty lines will be returned in text procols (if not, they are skipped)
Definition at line 308 of file socket.cc.
References _empty_lines.
00309 { 00310 _empty_lines = true; 00311 }
bool Network::Socket::connected | ( | ) | const |
return true when socket is connected
Definition at line 303 of file socket.cc.
References _socket.
Referenced by enable_tls().
00304 { 00305 return _socket != 0; 00306 }
void Network::Socket::del_delim | ( | const std::string & | delim | ) |
void Network::Socket::enable_tls | ( | ) |
Enable TLS on socket.
Definition at line 69 of file socket.cc.
References _kind, _socket, connected(), HERE, and Network::TCP.
00070 { 00071 #ifdef TLS 00072 int ret; 00073 00074 if (_kind != TCP) 00075 throw TLSError("You need to have a TCP connection", HERE); 00076 if (!connected()) 00077 throw NoConnection("You need to have a connection", HERE); 00078 00079 gnutls_transport_set_ptr(_session, (gnutls_transport_ptr)_socket); 00080 ret = gnutls_handshake(_session); 00081 if (ret < 0) 00082 { 00083 close(_socket); 00084 gnutls_deinit(_session); 00085 throw TLSError(gnutls_strerror(ret), HERE); 00086 } 00087 #else 00088 throw TLSSupportError("lib was not compiled with TLS support", HERE); 00089 #endif 00090 }
int Network::Socket::get_socket | ( | ) |
void Network::Socket::init_tls | ( | GnuTLSKind | kind, | |
unsigned | size = 1024 , |
|||
const std::string & | certfile = "" , |
|||
const std::string & | keyfile = "" , |
|||
const std::string & | trustfile = "" , |
|||
const std::string & | crlfile = "" | |||
) |
TLSSupportError | when TLS is not enabled |
Definition at line 92 of file socket.cc.
00097 { 00098 #ifdef TLS 00099 static bool init = false; 00100 static gnutls_dh_params dh_params; 00101 const int protocol_tls[] = { GNUTLS_TLS1, 0 }; 00102 const int protocol_ssl[] = { GNUTLS_SSL3, 0 }; 00103 const int cert_type_priority[] = { GNUTLS_CRT_X509, 00104 GNUTLS_CRT_OPENPGP, 0 }; 00105 00106 if (!init) 00107 { 00108 gnutls_global_init(); 00109 init = true; 00110 } 00111 _tls = true; 00112 _tls_main = true; 00113 gnutls_certificate_allocate_credentials(&_x509_cred); 00114 if (keyfile.size() > 0 && certfile.size() > 0) 00115 { 00116 std::ifstream key(keyfile.c_str()), cert(certfile.c_str()); 00117 if (!key.is_open() || !cert.is_open()) 00118 throw InvalidFile("key or cert invalid", HERE); 00119 key.close(); 00120 cert.close(); 00121 // Only for server... 00122 _nbbits = size; 00123 if (trustfile.size() > 0) 00124 gnutls_certificate_set_x509_trust_file(_x509_cred, trustfile.c_str(), 00125 GNUTLS_X509_FMT_PEM); 00126 if (crlfile.size() > 0) 00127 gnutls_certificate_set_x509_crl_file(_x509_cred, crlfile.c_str(), 00128 GNUTLS_X509_FMT_PEM); 00129 gnutls_certificate_set_x509_key_file(_x509_cred, certfile.c_str(), 00130 keyfile.c_str(), 00131 GNUTLS_X509_FMT_PEM); 00132 gnutls_dh_params_init(&dh_params); 00133 gnutls_dh_params_generate2(dh_params, _nbbits); 00134 gnutls_certificate_set_dh_params(_x509_cred, dh_params); 00135 00136 if (gnutls_init(&_session, GNUTLS_SERVER)) 00137 throw TLSError("gnutls_init failed", HERE); 00138 } 00139 else 00140 { 00141 if (gnutls_init(&_session, GNUTLS_CLIENT)) 00142 throw TLSError("gnutls_init failed", HERE); 00143 } 00144 00145 gnutls_set_default_priority(_session); 00146 if (kind == TLS) 00147 gnutls_protocol_set_priority(_session, protocol_tls); 00148 else 00149 gnutls_protocol_set_priority(_session, protocol_ssl); 00150 00151 if (keyfile.size() > 0 && certfile.size() > 0) 00152 { 00153 gnutls_credentials_set(_session, GNUTLS_CRD_CERTIFICATE, _x509_cred); 00154 gnutls_certificate_server_set_request(_session, GNUTLS_CERT_REQUEST); 00155 gnutls_dh_set_prime_bits(_session, _nbbits); 00156 } 00157 else 00158 { 00159 gnutls_certificate_type_set_priority(_session, cert_type_priority); 00160 gnutls_credentials_set(_session, GNUTLS_CRD_CERTIFICATE, _x509_cred); 00161 } 00162 #else 00163 throw TLSSupportError("lib was not compiled with TLS support", HERE); 00164 #endif 00165 }
virtual std::string Network::Socket::read | ( | int | timeout | ) | [pure virtual] |
read a string with a timeout
Implemented in Network::LocalSocket, and Network::NetSocket.
virtual std::string Network::Socket::read | ( | ) | [pure virtual] |
function used by >> operator (read a string on current socket)
Implemented in Network::LocalSocket, and Network::NetSocket.
virtual std::string Network::Socket::readn | ( | int | timeout, | |
unsigned int | size | |||
) | [pure virtual] |
read a string with a timeout
size | represente the number of byte to read |
Implemented in Network::LocalSocket, and Network::NetSocket.
virtual std::string Network::Socket::readn | ( | unsigned int | size | ) | [pure virtual] |
read a string from socket
size | represente the number of byte to read |
Implemented in Network::LocalSocket, and Network::NetSocket.
void Network::Socket::write | ( | const std::string & | str | ) |
function used by << operator (write a string on current socket)
Definition at line 295 of file socket.cc.
References _proto_kind, _socket, _write_str(), _write_str_bin(), and Network::binary.
00296 { 00297 if (_proto_kind == binary) 00298 _write_str_bin(_socket, str); 00299 else 00300 _write_str(_socket, str); 00301 }
struct sockaddr_in Network::Socket::_addr [protected] |
Definition at line 195 of file socket.hh.
Referenced by _write_str(), and _write_str_bin().
std::string Network::Socket::_buffer [protected] |
Definition at line 202 of file socket.hh.
Referenced by _check_answer(), and _update_buffer().
std::list<std::string> Network::Socket::_delim [protected] |
Definition at line 200 of file socket.hh.
Referenced by _find_delim(), add_delim(), del_delim(), and Socket().
bool Network::Socket::_empty_lines [protected] |
Definition at line 201 of file socket.hh.
Referenced by _update_buffer(), and allow_empty_lines().
SOCKET_KIND Network::Socket::_kind [protected] |
Definition at line 190 of file socket.hh.
Referenced by enable_tls().
PROTO_KIND Network::Socket::_proto_kind [protected] |
int Network::Socket::_recv_flags [protected] |
int Network::Socket::_socket [protected] |
Definition at line 193 of file socket.hh.
Referenced by Network::UdpSocket::connect(), Network::TcpSocket::connect(), connected(), enable_tls(), get_socket(), Network::LocalSocket::init(), Network::TcpSocket::TcpSocket(), and write().
unsigned Network::Socket::_state_timeout [protected] |
Definition at line 192 of file socket.hh.
Referenced by _check_answer().
bool Network::Socket::_tls [protected] |
Definition at line 203 of file socket.hh.
Referenced by _close(), _write_str(), _write_str_bin(), and init_tls().
SOCKET_VERSION Network::Socket::_version [protected] |
Definition at line 191 of file socket.hh.
Referenced by _write_str(), and _write_str_bin().