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 if (_kind == TCP && setsockopt(s, SOL_SOCKET,
00161 SO_REUSEADDR, (void *)&on,
00162 sizeof (on)) == -1)
00163 throw SetsockoptError("setsockopt error", HERE);
00164
00165 #ifdef IPV6_ENABLED
00166 if (_version == V4)
00167 {
00168 #endif
00169 struct sockaddr_in addr;
00170 addr = _get_addr(port);
00171 if (bind(s,(struct sockaddr*)&addr, (int)sizeof(addr)) == -1)
00172 throw BindError("Bind error", HERE);
00173 #ifdef IPV6_ENABLED
00174 }
00175 else
00176 {
00177 struct sockaddr_in6 addr6;
00178 addr6 = _get_addr6(port);
00179 if (bind(s,(struct sockaddr*)&addr6, (int)sizeof(addr6)) == -1)
00180 throw BindError("Bind error", HERE);
00181 }
00182 #endif
00183 return s;
00184 }
00185
00186 void NetSocket::_connect(int socket, int port,
00187 const std::string& host) const
00188 {
00189 #ifdef IPV6_ENABLED
00190 if (_version == V4)
00191 {
00192 #endif
00193 struct sockaddr_in addr;
00194 addr = _get_addr(host, port);
00195 if (connect(socket, (struct sockaddr *)&addr,
00196 sizeof (addr)) < 0)
00197 throw ConnectError("Unable to connect", HERE);
00198 #ifdef IPV6_ENABLED
00199 }
00200 else
00201 {
00202 struct sockaddr_in6 addr6;
00203 addr6 = _get_addr6(host, port);
00204 if (connect(socket, (struct sockaddr *)&addr6,
00205 sizeof (addr6)) < 0)
00206 throw ConnectError("Unable to connect", HERE);
00207 }
00208 #endif
00209 }
00210
00211 int NetSocket::_accept(int port, int socket) const
00212 {
00213 #ifdef LIBSOCKET_WIN
00214 int size;
00215 #else
00216 socklen_t size;
00217 #endif
00218 int s;
00219 struct sockaddr_in addr;
00220 #ifdef IPV6_ENABLED
00221 struct sockaddr_in6 addr6;
00222
00223 if (_version == V4)
00224 {
00225 #endif
00226 addr = _get_addr(port);
00227 size = sizeof(addr);
00228 s = accept(socket, (struct sockaddr*)&addr, &size);
00229 #ifdef IPV6_ENABLED
00230 }
00231 else
00232 {
00233 addr6 = _get_addr6(port);
00234 size = sizeof(addr6);
00235 s = accept(socket, (struct sockaddr*)&addr6, &size);
00236 }
00237 #endif
00238 if (s < 0)
00239 throw AcceptError("Accept Error", HERE);
00240 return s;
00241 }
00242
00243 std::string NetSocket::_get_ip(int port, int socket) const
00244 {
00245 struct sockaddr_in addr;
00246 #ifdef LIBSOCKET_WIN
00247 int size;
00248 #else
00249 socklen_t size;
00250 #endif
00251
00252 memset(&addr, '\0', sizeof(addr));
00253 addr.sin_family = AF_INET;
00254 addr.sin_addr.s_addr = htonl(INADDR_ANY);
00255 addr.sin_port = htons(port);
00256 size = sizeof(addr);
00257 getpeername(socket, (struct sockaddr *)&addr, &size);
00258 return(std::string(inet_ntoa(addr.sin_addr)));
00259 }
00260
00261 std::string NetSocket::_read_line(int socket)
00262 {
00263 char chr[MAXPKTSIZE];
00264 std::string str = "";
00265 int res = 1, i;
00266 std::pair<int, int> delim;
00267 bool end = false;
00268
00269 if (socket < 0)
00270 throw NoConnection("No Socket", HERE);
00271 if (!_update_buffer(delim, i, str))
00272 while (!end)
00273 {
00274 memset(chr, 0, MAXPKTSIZE);
00275 if (_state_timeout)
00276 _set_timeout(true, _socket, _state_timeout);
00277 if (_kind == UDP)
00278 #ifdef LIBSOCKET_WIN
00279 res = recv(socket, chr, MAXPKTSIZE, 0);
00280 #else
00281 res = recv(socket, chr, MAXPKTSIZE, MSG_TRUNC);
00282 #endif
00283 else
00284 #ifdef TLS
00285 if (_tls)
00286 res = gnutls_record_recv(_session, chr, MAXPKTSIZE);
00287 else
00288 #endif
00289 res = recv(socket, chr, MAXPKTSIZE, 0);
00290 if (_check_answer(res, str))
00291 return str;
00292 _buffer += std::string(chr, res);
00293 if (_update_buffer(delim, i, str))
00294 end = true;
00295 }
00296 _state_timeout = 0;
00297 return str;
00298 }
00299
00300 std::string NetSocket::_read_line(int socket, int& port,
00301 std::string& host)
00302 {
00303 char chr[MAXPKTSIZE];
00304 std::string str = "";
00305 int res = 1, i;
00306 std::pair<int, int> delim;
00307 struct sockaddr_in addr;
00308 #ifdef IPV6_ENABLED
00309 struct sockaddr_in6 addr6;
00310 #endif
00311 #ifdef LIBSOCKET_WIN
00312 int size;
00313 #else
00314 socklen_t size;
00315 #endif
00316 bool end = false;
00317
00318 #ifdef IPV6_ENABLED
00319 if (V4 == _version)
00320 #endif
00321 size = sizeof(addr);
00322 #ifdef IPV6_ENABLED
00323 else
00324 size = sizeof(addr6);
00325 #endif
00326 if (socket < 0)
00327 throw NoConnection("No Socket", HERE);
00328 if (!_update_buffer(delim, i, str))
00329 while (!end)
00330 {
00331 if (_state_timeout)
00332 _set_timeout(true, _socket, _state_timeout);
00333 if (_kind == UDP)
00334 {
00335 #ifdef LIBSOCKET_WIN
00336 int flags = 0;
00337 #else
00338 int flags = MSG_TRUNC;
00339 #endif
00340
00341 #ifdef IPV6_ENABLED
00342 if (V4 == _version)
00343 #endif
00344 res = recvfrom(socket, chr, MAXPKTSIZE, flags,
00345 (struct sockaddr *) &addr, &size);
00346 #ifdef IPV6_ENABLED
00347 else
00348 res = recvfrom(socket, chr, MAXPKTSIZE, flags,
00349 (struct sockaddr *) &addr6, &size);
00350 #endif
00351 }
00352 else
00353 {
00354 #ifdef TLS
00355 if (_tls)
00356 res = gnutls_record_recv(_session, chr, MAXPKTSIZE);
00357 else
00358 #endif
00359 res = recvfrom(socket, chr, MAXPKTSIZE, 0, NULL, 0);
00360 #ifdef IPV6_ENABLED
00361 if (V4 == _version)
00362 {
00363 #endif
00364 if (getpeername(socket, (struct sockaddr *) &addr, &size) < 0)
00365 throw GetpeernameError("getpeername error", HERE);
00366 #ifdef IPV6_ENABLED
00367 }
00368 else
00369 if (getpeername(socket, (struct sockaddr *) &addr6, &size) < 0)
00370 throw GetpeernameError("getpeername error", HERE);
00371 #endif
00372 }
00373 if (_check_answer(res, str))
00374 return str;
00375 _buffer += std::string(chr, res);
00376 if (_update_buffer(delim, i, str))
00377 end = true;
00378 }
00379 #ifdef IPV6_ENABLED
00380 if (V4 == _version)
00381 {
00382 #endif
00383 host = std::string(inet_ntoa(addr.sin_addr));
00384 port = ntohs(addr.sin_port);
00385 #ifdef IPV6_ENABLED
00386 }
00387 else
00388 {
00389 char buf[INET6_ADDRSTRLEN];
00390 if (inet_ntop(AF_INET6, &addr6.sin6_addr, buf, INET6_ADDRSTRLEN) == 0)
00391 throw InetntopError("Not a valid address", HERE);
00392 host = std::string(buf);
00393 port = ntohs(addr6.sin6_port);
00394 }
00395 #endif
00396 _state_timeout = 0;
00397 return str;
00398 }
00399
00400 void NetSocket::_write_str(int socket, const std::string& str,
00401 const std::string& host, int port) const
00402 {
00403 struct sockaddr_in addr;
00404 #ifdef IPV6_ENABLED
00405 struct sockaddr_in6 addr6;
00406 #endif
00407 int res = 1;
00408 const char *buf = str.c_str();
00409 unsigned int count = 0;
00410
00411 #ifdef IPV6_ENABLED
00412 if (V4 == _version)
00413 #endif
00414 addr = _get_addr(host, port);
00415 #ifdef IPV6_ENABLED
00416 else
00417 addr6 = _get_addr6(host, port);
00418 #endif
00419 if (socket < 0)
00420 throw NoConnection("No Socket", HERE);
00421 while (res && count < str.size())
00422 {
00423 #ifdef IPV6_ENABLED
00424 if (V4 == _version)
00425 #endif
00426 #ifdef TLS
00427 if (_tls)
00428 res = gnutls_record_send(_session, buf + count, str.size() - count);
00429 else
00430 #endif
00431 res = sendto(socket, buf + count,
00432 str.size() - count, SENDTO_FLAGS,
00433 (const struct sockaddr*)&addr, sizeof(_addr));
00434 #ifdef IPV6_ENABLED
00435 else
00436 res = sendto(socket, buf + count,
00437 str.size() - count, SENDTO_FLAGS,
00438 (const struct sockaddr*)&addr6, sizeof(_addr6));
00439 #endif
00440 if (res <= 0)
00441 throw ConnectionClosed("Connection Closed", HERE);
00442 count += res;
00443 }
00444 }
00445
00446 void NetSocket::_write_str_bin(int socket, const std::string& str,
00447 const std::string& host, int port) const
00448 {
00449 struct sockaddr_in addr;
00450 #ifdef IPV6_ENABLED
00451 struct sockaddr_in6 addr6;
00452 #endif
00453 int res = 1;
00454 unsigned int count = 0;
00455 #ifdef LIBSOCKET_WIN
00456 char* buf = new char[str.size() + 2];
00457 #else
00458 char buf[str.size() + 2];
00459 #endif
00460
00461 buf[0] = str.size() / 256;
00462 buf[1] = str.size() % 256;
00463 memcpy(buf + 2, str.c_str(), str.size());
00464 #ifdef IPV6_ENABLED
00465 if (V4 == _version)
00466 #endif
00467 addr = _get_addr(host, port);
00468 #ifdef IPV6_ENABLED
00469 else
00470 addr6 = _get_addr6(host, port);
00471 #endif
00472 if (socket < 0)
00473 throw NoConnection("No Socket", HERE);
00474 while (res && count < str.size() + 2)
00475 {
00476 #ifdef IPV6_ENABLED
00477 if (V4 == _version)
00478 #endif
00479 #ifdef TLS
00480 if (_tls)
00481 res = gnutls_record_send(_session, buf + count, str.size() + 2 - count);
00482 else
00483 #endif
00484 res = sendto(socket, buf + count, str.size() + 2 - count,
00485 SENDTO_FLAGS,
00486 (const struct sockaddr*)&addr, sizeof(_addr));
00487 #ifdef IPV6_ENABLED
00488 else
00489 res = sendto(socket, buf + count, str.size() + 2 - count,
00490 SENDTO_FLAGS,
00491 (const struct sockaddr*)&addr6, sizeof(_addr6));
00492 #endif
00493 if (res <= 0)
00494 throw ConnectionClosed("Connection Closed", HERE);
00495 count += res;
00496 }
00497 #ifdef LIBSOCKET_WIN
00498 delete[] buf;
00499 #endif
00500 }
00501
00502 void NetSocket::writeto(const std::string& str,
00503 const std::string& host, int port)
00504 {
00505 if (_proto_kind == binary)
00506 _write_str_bin(_socket, str, host, port);
00507 else
00508 _write_str(_socket, str, host, port);
00509 }
00510
00511 std::string NetSocket::read(int& port, std::string& host)
00512 {
00513 if (_proto_kind == binary)
00514 return _read_line_bin(_socket, port, host, 0);
00515 else
00516 return _read_line(_socket, port, host);
00517 }
00518
00519 std::string NetSocket::read(int& port, std::string& host, int timeout)
00520 {
00521 if (_proto_kind == binary)
00522 {
00523 _set_timeout(true, _socket, timeout);
00524 return _read_line_bin(_socket, port, host, 0);
00525 }
00526 else
00527 {
00528 _state_timeout = timeout;
00529 return _read_line(_socket, port, host);
00530 }
00531 }
00532
00533 std::string NetSocket::read()
00534 {
00535 if (_proto_kind == binary)
00536 return _read_line_bin(_socket, 0);
00537 else
00538 return _read_line(_socket);
00539 }
00540
00541 std::string NetSocket::read(int timeout)
00542 {
00543 if (_proto_kind == binary)
00544 {
00545 _set_timeout(true, _socket, timeout);
00546 return _read_line_bin(_socket, 0);
00547 }
00548 else
00549 {
00550 _state_timeout = timeout;
00551 return _read_line(_socket);
00552 }
00553 }
00554
00555 std::string NetSocket::readn(int& port, std::string& host,
00556 unsigned int size)
00557 {
00558
00559
00560
00561 return _read_line_bin(_socket, port, host, size);
00562 }
00563
00564 std::string NetSocket::readn(int& port, std::string& host, int timeout,
00565 unsigned int size)
00566 {
00567 if (!size || size > _buffer.size())
00568 _set_timeout(true, _socket, timeout);
00569
00570
00571
00572 return _read_line_bin(_socket, port, host, size);
00573 }
00574
00575 std::string NetSocket::readn(unsigned int size)
00576 {
00577
00578
00579
00580 return _read_line_bin(_socket, size);
00581 }
00582
00583 std::string NetSocket::readn(int timeout, unsigned int size)
00584 {
00585 if (!size || size > _buffer.size())
00586 _set_timeout(true, _socket, timeout);
00587
00588
00589
00590 return _read_line_bin(_socket, size);
00591 }
00592 }