00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <iostream>
00024 #include "netsocket.hh"
00025 #include "socket.hxx"
00026
00027 namespace Network
00028 {
00029
00030 struct sockaddr_in NetSocket::_get_addr(const std::string& host,
00031 int port) const
00032 {
00033 struct hostent *he;
00034 struct sockaddr_in addr;
00035
00036 memset(&addr, 0, sizeof(struct sockaddr_in));
00037 he = gethostbyname(host.c_str());
00038 if (!he)
00039 throw HostnameError("Unknown Hostname", HERE);
00040 addr.sin_addr = *((struct in_addr *)he->h_addr);
00041 addr.sin_port = htons(port);
00042 addr.sin_family = AF_INET;
00043 return addr;
00044 }
00045
00046 #ifdef IPV6_ENABLED
00047 struct sockaddr_in6 NetSocket::_get_addr6(const std::string& host,
00048 int port) const
00049 {
00050 struct sockaddr_in6 addr;
00051
00052 memset(&addr, 0, sizeof(struct sockaddr_in6));
00053 if ( inet_pton(AF_INET6, host.c_str(), &addr.sin6_addr) == 0 )
00054 throw InetptonError("Unknown Hostname", HERE);
00055 addr.sin6_port = htons(port);
00056 addr.sin6_family = AF_INET6;
00057 return addr;
00058 }
00059 #endif
00060
00061 struct sockaddr_in NetSocket::_get_addr(int port) const
00062 {
00063 struct sockaddr_in addr;
00064
00065 memset(&addr, 0, sizeof(struct sockaddr_in));
00066 addr.sin_addr.s_addr = htonl(INADDR_ANY);
00067 addr.sin_port = htons(port);
00068 addr.sin_family = AF_INET;
00069 return addr;
00070 }
00071
00072 #ifdef IPV6_ENABLED
00073 struct sockaddr_in6 NetSocket::_get_addr6(int port) const
00074 {
00075 struct sockaddr_in6 addr;
00076
00077 memset(&addr, 0, sizeof(struct sockaddr_in6));
00078 if ( inet_pton(AF_INET6, "0::0", &addr.sin6_addr) == 0 )
00079 throw InetptonError("Not a valid address", HERE);
00080 addr.sin6_port = htons(port);
00081 addr.sin6_family = AF_INET6;
00082 return addr;
00083 }
00084 #endif
00085
00086 int NetSocket::_bind(int port, const std::string& host)
00087 {
00088 int s;
00089
00090 if (_kind == UDP)
00091 {
00092 #ifdef IPV6_ENABLED
00093 if (_version == V4)
00094 #endif
00095 s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
00096 #ifdef IPV6_ENABLED
00097 else
00098 s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
00099 #endif
00100 }
00101 else if (_kind == TCP)
00102 {
00103 #ifdef IPV6_ENABLED
00104 if (_version == V4)
00105 #endif
00106 s = socket(PF_INET, SOCK_STREAM, 0);
00107 #ifdef IPV6_ENABLED
00108 else
00109 s = socket(PF_INET6, SOCK_STREAM, 0);
00110 #endif
00111 }
00112 else
00113 throw Exception("Unknown Protocole", HERE);
00114
00115 if (s < 0)
00116 throw SocketError("Socket error", HERE);
00117 #ifdef IPV6_ENABLED
00118 if (_version == V4)
00119 #endif
00120 _addr = _get_addr(host, port);
00121 #ifdef IPV6_ENABLED
00122 else
00123 _addr6 = _get_addr6(host, port);
00124 #endif
00125 return s;
00126 }
00127
00128 int NetSocket::_bind(int port)
00129 {
00130 int s, on;
00131
00132 if (_kind == TCP)
00133 {
00134 #ifdef IPV6_ENABLED
00135 if (_version == V4)
00136 #endif
00137 s = socket(PF_INET, SOCK_STREAM, 0);
00138 #ifdef IPV6_ENABLED
00139 else
00140 s = socket(PF_INET6, SOCK_STREAM, 0);
00141 #endif
00142 }
00143 else if (_kind == UDP)
00144 {
00145 #ifdef IPV6_ENABLED
00146 if (_version == V4)
00147 #endif
00148 s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
00149 #ifdef IPV6_ENABLED
00150 else
00151 s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
00152 #endif
00153 }
00154 else
00155 throw Exception("Unknown Protocole", HERE);
00156 if (s < 0)
00157 throw SocketError("Socket error", HERE);
00158 on = 1;
00159
00160 #ifndef LIBSOCKET_WIN
00161 if (_kind == TCP && setsockopt(s, SOL_SOCKET,
00162 SO_REUSEADDR, (void *)&on,
00163 sizeof (on)) == -1)
00164 throw SetsockoptError("setsockopt error", HERE);
00165 #endif
00166
00167 #ifdef IPV6_ENABLED
00168 if (_version == V4)
00169 {
00170 #endif
00171 struct sockaddr_in addr;
00172 addr = _get_addr(port);
00173 if (bind(s,(struct sockaddr*)&addr, (int)sizeof(addr)) == -1)
00174 throw BindError("Bind error", HERE);
00175 #ifdef IPV6_ENABLED
00176 }
00177 else
00178 {
00179 struct sockaddr_in6 addr6;
00180 addr6 = _get_addr6(port);
00181 if (bind(s,(struct sockaddr*)&addr6, (int)sizeof(addr6)) == -1)
00182 throw BindError("Bind error", HERE);
00183 }
00184 #endif
00185 return s;
00186 }
00187
00188 void NetSocket::_connect(int socket, int port,
00189 const std::string& host) const
00190 {
00191 #ifdef IPV6_ENABLED
00192 if (_version == V4)
00193 {
00194 #endif
00195 struct sockaddr_in addr;
00196 addr = _get_addr(host, port);
00197 if (connect(socket, (struct sockaddr *)&addr,
00198 sizeof (addr)) < 0)
00199 throw ConnectError("Unable to connect", HERE);
00200 #ifdef IPV6_ENABLED
00201 }
00202 else
00203 {
00204 struct sockaddr_in6 addr6;
00205 addr6 = _get_addr6(host, port);
00206 if (connect(socket, (struct sockaddr *)&addr6,
00207 sizeof (addr6)) < 0)
00208 throw ConnectError("Unable to connect", HERE);
00209 }
00210 #endif
00211 }
00212
00213 int NetSocket::_accept(int port, int socket) const
00214 {
00215 #ifdef LIBSOCKET_WIN
00216 int size;
00217 #else
00218 socklen_t size;
00219 #endif
00220 int s;
00221 struct sockaddr_in addr;
00222 #ifdef IPV6_ENABLED
00223 struct sockaddr_in6 addr6;
00224
00225 if (_version == V4)
00226 {
00227 #endif
00228 addr = _get_addr(port);
00229 size = sizeof(addr);
00230 s = accept(socket, (struct sockaddr*)&addr, &size);
00231 #ifdef IPV6_ENABLED
00232 }
00233 else
00234 {
00235 addr6 = _get_addr6(port);
00236 size = sizeof(addr6);
00237 s = accept(socket, (struct sockaddr*)&addr6, &size);
00238 }
00239 #endif
00240 if (s < 0)
00241 throw AcceptError("Accept Error", HERE);
00242 return s;
00243 }
00244
00245 std::string NetSocket::_get_ip(int port, int socket) const
00246 {
00247 struct sockaddr_in addr;
00248 #ifdef LIBSOCKET_WIN
00249 int size;
00250 #else
00251 socklen_t size;
00252 #endif
00253
00254 memset(&addr, '\0', sizeof(addr));
00255 addr.sin_family = AF_INET;
00256 addr.sin_addr.s_addr = htonl(INADDR_ANY);
00257 addr.sin_port = htons(port);
00258 size = sizeof(addr);
00259 getpeername(socket, (struct sockaddr *)&addr, &size);
00260 return(std::string(inet_ntoa(addr.sin_addr)));
00261 }
00262
00263 std::string NetSocket::_read_line(int socket)
00264 {
00265 char chr[MAXPKTSIZE];
00266 std::string str = "";
00267 int res = 1, i;
00268 std::pair<int, int> delim;
00269 bool end = false;
00270
00271 if (socket < 0)
00272 throw NoConnection("No Socket", HERE);
00273 if (!_update_buffer(delim, i, str))
00274 while (!end)
00275 {
00276 memset(chr, 0, MAXPKTSIZE);
00277 if (_state_timeout)
00278 _set_timeout(true, _socket, _state_timeout);
00279 if (_kind == UDP)
00280 #ifdef LIBSOCKET_WIN
00281 res = recv(socket, chr, MAXPKTSIZE, 0);
00282 #else
00283 res = recv(socket, chr, MAXPKTSIZE, MSG_TRUNC);
00284 #endif
00285 else
00286 #ifdef TLS
00287 if (_tls)
00288 res = gnutls_record_recv(_session, chr, MAXPKTSIZE);
00289 else
00290 #endif
00291 res = recv(socket, chr, MAXPKTSIZE, 0);
00292 if (_check_answer(res, str))
00293 return str;
00294 _buffer += std::string(chr, res);
00295 if (_update_buffer(delim, i, str))
00296 end = true;
00297 }
00298 _state_timeout = 0;
00299 return str;
00300 }
00301
00302 std::string NetSocket::_read_line(int socket, int& port,
00303 std::string& host)
00304 {
00305 char chr[MAXPKTSIZE];
00306 std::string str = "";
00307 int res = 1, i;
00308 std::pair<int, int> delim;
00309 struct sockaddr_in addr;
00310 #ifdef IPV6_ENABLED
00311 struct sockaddr_in6 addr6;
00312 #endif
00313 #ifdef LIBSOCKET_WIN
00314 int size;
00315 #else
00316 socklen_t size;
00317 #endif
00318 bool end = false;
00319
00320 #ifdef IPV6_ENABLED
00321 if (V4 == _version)
00322 #endif
00323 size = sizeof(addr);
00324 #ifdef IPV6_ENABLED
00325 else
00326 size = sizeof(addr6);
00327 #endif
00328 if (socket < 0)
00329 throw NoConnection("No Socket", HERE);
00330 if (!_update_buffer(delim, i, str))
00331 while (!end)
00332 {
00333 if (_state_timeout)
00334 _set_timeout(true, _socket, _state_timeout);
00335 if (_kind == UDP)
00336 {
00337 #ifdef LIBSOCKET_WIN
00338 int flags = 0;
00339 #else
00340 int flags = MSG_TRUNC;
00341 #endif
00342
00343 #ifdef IPV6_ENABLED
00344 if (V4 == _version)
00345 #endif
00346 res = recvfrom(socket, chr, MAXPKTSIZE, flags,
00347 (struct sockaddr *) &addr, &size);
00348 #ifdef IPV6_ENABLED
00349 else
00350 res = recvfrom(socket, chr, MAXPKTSIZE, flags,
00351 (struct sockaddr *) &addr6, &size);
00352 #endif
00353 }
00354 else
00355 {
00356 #ifdef TLS
00357 if (_tls)
00358 res = gnutls_record_recv(_session, chr, MAXPKTSIZE);
00359 else
00360 #endif
00361 res = recvfrom(socket, chr, MAXPKTSIZE, 0, NULL, 0);
00362 #ifdef IPV6_ENABLED
00363 if (V4 == _version)
00364 {
00365 #endif
00366 if (getpeername(socket, (struct sockaddr *) &addr, &size) < 0)
00367 throw GetpeernameError("getpeername error", HERE);
00368 #ifdef IPV6_ENABLED
00369 }
00370 else
00371 if (getpeername(socket, (struct sockaddr *) &addr6, &size) < 0)
00372 throw GetpeernameError("getpeername error", HERE);
00373 #endif
00374 }
00375 if (_check_answer(res, str))
00376 return str;
00377 _buffer += std::string(chr, res);
00378 if (_update_buffer(delim, i, str))
00379 end = true;
00380 }
00381 #ifdef IPV6_ENABLED
00382 if (V4 == _version)
00383 {
00384 #endif
00385 host = std::string(inet_ntoa(addr.sin_addr));
00386 port = ntohs(addr.sin_port);
00387 #ifdef IPV6_ENABLED
00388 }
00389 else
00390 {
00391 char buf[INET6_ADDRSTRLEN];
00392 if (inet_ntop(AF_INET6, &addr6.sin6_addr, buf, INET6_ADDRSTRLEN) == 0)
00393 throw InetntopError("Not a valid address", HERE);
00394 host = std::string(buf);
00395 port = ntohs(addr6.sin6_port);
00396 }
00397 #endif
00398 _state_timeout = 0;
00399 return str;
00400 }
00401
00402 void NetSocket::_write_str(int socket, const std::string& str,
00403 const std::string& host, int port) const
00404 {
00405 struct sockaddr_in addr;
00406 #ifdef IPV6_ENABLED
00407 struct sockaddr_in6 addr6;
00408 #endif
00409 int res = 1;
00410 const char *buf = str.c_str();
00411 unsigned int count = 0;
00412
00413 #ifdef IPV6_ENABLED
00414 if (V4 == _version)
00415 #endif
00416 addr = _get_addr(host, port);
00417 #ifdef IPV6_ENABLED
00418 else
00419 addr6 = _get_addr6(host, port);
00420 #endif
00421 if (socket < 0)
00422 throw NoConnection("No Socket", HERE);
00423 while (res && count < str.size())
00424 {
00425 #ifdef IPV6_ENABLED
00426 if (V4 == _version)
00427 #endif
00428 #ifdef TLS
00429 if (_tls)
00430 res = gnutls_record_send(_session, buf + count, str.size() - count);
00431 else
00432 #endif
00433 res = sendto(socket, buf + count,
00434 str.size() - count, SENDTO_FLAGS,
00435 (const struct sockaddr*)&addr, sizeof(_addr));
00436 #ifdef IPV6_ENABLED
00437 else
00438 res = sendto(socket, buf + count,
00439 str.size() - count, SENDTO_FLAGS,
00440 (const struct sockaddr*)&addr6, sizeof(_addr6));
00441 #endif
00442 if (res <= 0)
00443 throw ConnectionClosed("Connection Closed", HERE);
00444 count += res;
00445 }
00446 }
00447
00448 void NetSocket::_write_str_bin(int socket, const std::string& str,
00449 const std::string& host, int port) const
00450 {
00451 struct sockaddr_in addr;
00452 #ifdef IPV6_ENABLED
00453 struct sockaddr_in6 addr6;
00454 #endif
00455 int res = 1;
00456 unsigned int count = 0;
00457 #ifdef LIBSOCKET_WIN
00458 char* buf = new char[str.size() + 2];
00459 #else
00460 char buf[str.size() + 2];
00461 #endif
00462
00463 buf[0] = str.size() / 256;
00464 buf[1] = str.size() % 256;
00465 memcpy(buf + 2, str.c_str(), str.size());
00466 #ifdef IPV6_ENABLED
00467 if (V4 == _version)
00468 #endif
00469 addr = _get_addr(host, port);
00470 #ifdef IPV6_ENABLED
00471 else
00472 addr6 = _get_addr6(host, port);
00473 #endif
00474 if (socket < 0)
00475 throw NoConnection("No Socket", HERE);
00476 while (res && count < str.size() + 2)
00477 {
00478 #ifdef IPV6_ENABLED
00479 if (V4 == _version)
00480 #endif
00481 #ifdef TLS
00482 if (_tls)
00483 res = gnutls_record_send(_session, buf + count, str.size() + 2 - count);
00484 else
00485 #endif
00486 res = sendto(socket, buf + count, str.size() + 2 - count,
00487 SENDTO_FLAGS,
00488 (const struct sockaddr*)&addr, sizeof(_addr));
00489 #ifdef IPV6_ENABLED
00490 else
00491 res = sendto(socket, buf + count, str.size() + 2 - count,
00492 SENDTO_FLAGS,
00493 (const struct sockaddr*)&addr6, sizeof(_addr6));
00494 #endif
00495 if (res <= 0)
00496 throw ConnectionClosed("Connection Closed", HERE);
00497 count += res;
00498 }
00499 #ifdef LIBSOCKET_WIN
00500 delete[] buf;
00501 #endif
00502 }
00503
00504 void NetSocket::writeto(const std::string& str,
00505 const std::string& host, int port)
00506 {
00507 if (_proto_kind == binary)
00508 _write_str_bin(_socket, str, host, port);
00509 else
00510 _write_str(_socket, str, host, port);
00511 }
00512
00513 std::string NetSocket::read(int& port, std::string& host)
00514 {
00515 if (_proto_kind == binary)
00516 return _read_line_bin(_socket, port, host, 0);
00517 else
00518 return _read_line(_socket, port, host);
00519 }
00520
00521 std::string NetSocket::read(int& port, std::string& host, int timeout)
00522 {
00523 if (_proto_kind == binary)
00524 {
00525 _set_timeout(true, _socket, timeout);
00526 return _read_line_bin(_socket, port, host, 0);
00527 }
00528 else
00529 {
00530 _state_timeout = timeout;
00531 return _read_line(_socket, port, host);
00532 }
00533 }
00534
00535 std::string NetSocket::read()
00536 {
00537 if (_proto_kind == binary)
00538 return _read_line_bin(_socket, 0);
00539 else
00540 return _read_line(_socket);
00541 }
00542
00543 std::string NetSocket::read(int timeout)
00544 {
00545 if (_proto_kind == binary)
00546 {
00547 _set_timeout(true, _socket, timeout);
00548 return _read_line_bin(_socket, 0);
00549 }
00550 else
00551 {
00552 _state_timeout = timeout;
00553 return _read_line(_socket);
00554 }
00555 }
00556
00557 std::string NetSocket::readn(int& port, std::string& host,
00558 unsigned int size)
00559 {
00560
00561
00562
00563 return _read_line_bin(_socket, port, host, size);
00564 }
00565
00566 std::string NetSocket::readn(int& port, std::string& host, int timeout,
00567 unsigned int size)
00568 {
00569 if (!size || size > _buffer.size())
00570 _set_timeout(true, _socket, timeout);
00571
00572
00573
00574 return _read_line_bin(_socket, port, host, size);
00575 }
00576
00577 std::string NetSocket::readn(unsigned int size)
00578 {
00579
00580
00581
00582 return _read_line_bin(_socket, size);
00583 }
00584
00585 std::string NetSocket::readn(int timeout, unsigned int size)
00586 {
00587 if (!size || size > _buffer.size())
00588 _set_timeout(true, _socket, timeout);
00589
00590
00591
00592 return _read_line_bin(_socket, size);
00593 }
00594 }