00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifdef WIN32
00016 #pragma warning (disable:4786)
00017 #endif
00018
00019 #include <API/Core/System/error.h>
00020 #include "API/Core/System/cl_assert.h"
00021 #include <Network/Generic/network_delivery_impl.h>
00022 #include <Network/Generic/network_delivery_socket.h>
00023
00024 #include <string.h>
00025 #include <errno.h>
00026
00027
00028
00029
00030 #define NETWORK_MAGIC 0x16042104
00031
00032
00033
00034
00035
00036 CL_UniformSocket::CL_UniformSocket(CL_ConnectionProvider *_provider)
00037 {
00038 provider = _provider;
00039 is_connection_lost = false;
00040 sock = CL_INVALID_SOCKET;
00041 send_pos = 0;
00042
00043 recv_state = expect_magic;
00044 cur_message = NULL;
00045 cur_message_size = -1;
00046 }
00047
00048 CL_UniformSocket::~CL_UniformSocket()
00049 {
00050 if (sock != CL_INVALID_SOCKET) closesocket(sock);
00051 provider->remove_connection(this);
00052 }
00053
00054 bool CL_UniformSocket::read_avail()
00055 {
00056 fd_set rfds;
00057
00058 FD_ZERO(&rfds);
00059 FD_SET(sock, &rfds);
00060
00061 timeval timeout;
00062 memset(&timeout, 0, sizeof(timeval));
00063
00064 int retval = select(sock+1, &rfds, NULL, NULL, &timeout);
00065 if (retval == -1 || retval == 0)
00066 {
00067 return false;
00068 }
00069
00070 char buf[1024];
00071
00072 int data_received = ::recv(
00073 sock,
00074 buf,
00075 1024,
00076 0);
00077
00078 if (data_received == 0 || data_received == -1)
00079 {
00080 is_connection_lost = true;
00081 return false;
00082 }
00083 recv_buffer.append(buf, data_received);
00084
00085 return true;
00086 }
00087
00088 bool CL_UniformSocket::require_avail(unsigned int size)
00089 {
00090 return recv_buffer.size() >= size;
00091 }
00092
00093 bool CL_UniformSocket::get_avail(void *buf, unsigned int size)
00094 {
00095 if (recv_buffer.size() < size) return false;
00096
00097 memcpy(buf, recv_buffer.data(), size);
00098 recv_buffer.erase(0, size);
00099
00100 return true;
00101 }
00102
00103 bool CL_UniformSocket::init_socket(int init_socket)
00104 {
00105 static int sol_tcp = -1;
00106 if (sol_tcp == -1) sol_tcp = getprotobyname("tcp")->p_proto;
00107
00108 if (init_socket != CL_INVALID_SOCKET)
00109 {
00110 sock = init_socket;
00111
00112
00113 #ifdef WIN32
00114 u_long argp = 1;
00115 ioctlsocket(sock, FIONBIO, &argp);
00116 #else
00117 fcntl(sock, F_SETFL, O_NONBLOCK);
00118 #endif
00119
00120 int value = 1;
00121 setsockopt(sock, sol_tcp, TCP_NODELAY, (const char *) &value, sizeof(int));
00122 write_int(NETWORK_MAGIC);
00123 }
00124 else
00125 {
00126 sock = socket(AF_INET, SOCK_STREAM, 0);
00127 if (sock == CL_INVALID_SOCKET) return false;
00128
00129
00130 #ifdef WIN32
00131 u_long argp = 1;
00132 ioctlsocket(sock, FIONBIO, &argp);
00133 #else
00134 fcntl(sock, F_SETFL, O_NONBLOCK);
00135 #endif
00136
00137 int value = 1;
00138 setsockopt(sock, sol_tcp, TCP_NODELAY, (const char *) &value, sizeof(int));
00139 }
00140
00141 return true;
00142 }
00143
00144 bool CL_UniformSocket::peek()
00145 {
00146 if (sock == CL_INVALID_SOCKET) return false;
00147
00148 read_avail();
00149 send_avail();
00150
00151 switch (recv_state)
00152 {
00153 case expect_magic:
00154 {
00155 int found_magic;
00156 if (get_avail(&found_magic, sizeof(int)) == false) return false;
00157 found_magic = ntohl(found_magic);
00158 if (found_magic != NETWORK_MAGIC)
00159 {
00160 is_connection_lost=true;
00161 }
00162 else recv_state = expect_packet_size;
00163 }
00164
00165 case expect_packet_size:
00166 {
00167 if (get_avail(&cur_message_size, sizeof(int)) == false) return false;
00168 cur_message_size = ntohl(cur_message_size);
00169 recv_state = expect_packet_data;
00170 }
00171
00172 case expect_packet_data:
00173 {
00174 if (!require_avail(cur_message_size)) return false;
00175 cur_message = new char[cur_message_size];
00176 get_avail(cur_message, cur_message_size);
00177 recv_state = packet_finished;
00178 }
00179
00180 case packet_finished:
00181 return true;
00182
00183 default:
00184 throw CL_Error("Network protocol error.");
00185 return false;
00186 };
00187
00188 return false;
00189 }
00190
00191 CL_ConnectionPacket CL_UniformSocket::receive()
00192 {
00193 if (peek() == false)
00194 {
00195 CL_ConnectionPacket ret;
00196 ret.size = 0;
00197 ret.data = NULL;
00198 return ret;
00199 }
00200
00201 CL_ConnectionPacket ret;
00202 ret.size = cur_message_size;
00203 ret.data = cur_message;
00204
00205 recv_state = expect_packet_size;
00206
00207 return ret;
00208 }
00209
00210 void CL_UniformSocket::send(CL_ConnectionPacket message)
00211 {
00212 write_int(message.size);
00213 write_data(message.data, message.size);
00214 }
00215
00216 bool CL_UniformSocket::connection_lost()
00217 {
00218 return is_connection_lost;
00219 }
00220
00221 unsigned long CL_UniformSocket::read_int()
00222 {
00223 unsigned char data[4];
00224 int read = 0;
00225 while (read < 4)
00226 {
00227 int val = recv(sock, (char *) data+read, 4-read, 0);
00228 if (val == 0 || val == -1)
00229 {
00230 is_connection_lost = true;
00231 return 0;
00232 }
00233
00234 read += val;
00235 }
00236
00237 return ntohl(*((unsigned long *) data));
00238 }
00239
00240 void CL_UniformSocket::write_int(unsigned long value)
00241 {
00242 unsigned long write_num = htonl(value);
00243
00244 write_data(&write_num, sizeof(unsigned long));
00245 }
00246
00247 void CL_UniformSocket::write_data(void *data, unsigned int size)
00248 {
00249 send_buffer.push(std::string((char *) data, size));
00250 send_avail();
00251 }
00252 #include <iostream>
00253 bool CL_UniformSocket::send_avail()
00254 {
00255 if (send_buffer.empty()) return true;
00256
00257 std::string &buf = send_buffer.front();
00258 int size = buf.size();
00259 int res = ::send(sock, buf.data()+send_pos, size-send_pos, 0);
00260 if (res == CL_SOCKET_ERROR)
00261 {
00262 #ifdef WIN32
00263 if (WSAGetLastError() == WSAEWOULDBLOCK) return false;
00264 #else
00265 if (errno == EAGAIN) return false;
00266 #endif
00267
00268 cl_info_debug(info_network, PRINT_SOCK_ERROR());
00269 is_connection_lost = true;
00270 return true;
00271 }
00272
00273 send_pos += res;
00274 if (send_pos == size)
00275 {
00276 send_buffer.pop();
00277 send_pos = 0;
00278 }
00279
00280 return send_buffer.empty();
00281 }
00282
00283 bool CL_UniformSocket::try_connect(unsigned long remote_ip_network_format, int port)
00284 {
00285 sockaddr_in sock_addr;
00286 sock_addr.sin_family = AF_INET;
00287 sock_addr.sin_addr.s_addr = remote_ip_network_format;
00288 sock_addr.sin_port = htons(port);
00289
00290 int res = ::connect(sock, (sockaddr *) &sock_addr, sizeof(sockaddr_in));
00291
00292 fd_set fdfailure, fdwrite;
00293 FD_ZERO(&fdfailure);
00294 FD_ZERO(&fdwrite);
00295 FD_SET(sock, &fdfailure);
00296 FD_SET(sock, &fdwrite);
00297 res = ::select(sock+1, NULL, &fdwrite, &fdfailure, NULL);
00298 if (res > 0)
00299 {
00300 if (FD_ISSET(sock, &fdfailure))
00301 {
00302 throw CL_Error("Connection refused");
00303 }
00304
00305 write_int(NETWORK_MAGIC);
00306
00307 return true;
00308 }
00309 else
00310 {
00311
00312 throw CL_Error(PRINT_SOCK_ERROR());
00313 return false;
00314 }
00315 }
00316
00317
00318
00319
00320
00321 CL_UniformAcceptSocket::CL_UniformAcceptSocket(CL_ConnectionProvider *provider)
00322 : CL_UniformSocket(provider)
00323 {
00324 port = -1;
00325 }
00326
00327 CL_UniformAcceptSocket::~CL_UniformAcceptSocket()
00328 {
00329 }
00330
00331 bool CL_UniformAcceptSocket::bind(int _port)
00332 {
00333 if (!init_socket()) return false;
00334
00335 sockaddr_in addr;
00336 addr.sin_family = AF_INET;
00337 addr.sin_addr.s_addr = INADDR_ANY;
00338 addr.sin_port = htons(_port);
00339
00340
00341 int err = ::bind(sock, (sockaddr *) &addr, sizeof(sockaddr_in));
00342 if (err == CL_SOCKET_ERROR) throw CL_Error(PRINT_SOCK_ERROR());
00343
00344
00345
00346 socklen_t len = sizeof(sockaddr_in);
00347 err = getsockname(sock, (sockaddr *) &addr, &len);
00348 if (err == CL_SOCKET_ERROR) throw CL_Error(PRINT_SOCK_ERROR());
00349
00350 port = ntohs(addr.sin_port);
00351
00352
00353 err = listen(sock, 64);
00354 if (err == CL_SOCKET_ERROR) throw CL_Error(PRINT_SOCK_ERROR());
00355
00356 return true;
00357 }
00358
00359 bool CL_UniformAcceptSocket::peek()
00360 {
00361 fd_set rfds;
00362
00363 FD_ZERO(&rfds);
00364 FD_SET(sock, &rfds);
00365
00366 timeval timeout;
00367 memset(&timeout, 0, sizeof(timeval));
00368
00369 int retval = select(sock+1, &rfds, NULL, NULL, &timeout);
00370 cl_assert(retval != -1);
00371
00372 if (retval == 0) return false;
00373 else return true;
00374 }
00375
00376 CL_UniformSocket *CL_UniformAcceptSocket::accept()
00377 {
00378 fd_set rfds;
00379 FD_ZERO(&rfds);
00380 FD_SET(sock, &rfds);
00381
00382 timeval timeout;
00383 memset(&timeout, 0, sizeof(timeval));
00384
00385 int retval = select(sock+1, &rfds, NULL, NULL, &timeout);
00386 if (retval == -1 || retval == 0)
00387 {
00388 return NULL;
00389 }
00390
00391 int res_sock = ::accept(sock, NULL, NULL);
00392 cl_assert(res_sock != CL_INVALID_SOCKET);
00393
00394 CL_UniformSocket *ret = new CL_UniformSocket(provider);
00395 ret->init_socket(res_sock);
00396
00397 return ret;
00398 }
00399
00400 bool CL_UniformAcceptSocket::try_connect(unsigned long remote_ip_network_format, int port)
00401 {
00402 cl_assert(false);
00403
00404 return false;
00405 }
00406
00407 CL_ConnectionPacket CL_UniformAcceptSocket::receive()
00408 {
00409 cl_assert(false);
00410 CL_ConnectionPacket ret;
00411 return ret;
00412 }
00413
00414 void CL_UniformAcceptSocket::send(CL_ConnectionPacket message)
00415 {
00416 cl_assert(false);
00417 }
00418
00419 bool CL_UniformAcceptSocket::connection_lost()
00420 {
00421 cl_assert(false);
00422 return false;
00423 }
00424
00425
00426
00427
00428
00429 CL_UniformUDPConnection::CL_UniformUDPConnection()
00430 {
00431 sock = CL_INVALID_SOCKET;
00432 port = -1;
00433 }
00434
00435 CL_UniformUDPConnection::~CL_UniformUDPConnection()
00436 {
00437 if (sock != CL_INVALID_SOCKET) closesocket(sock);
00438 }
00439
00440 bool CL_UniformUDPConnection::bind(unsigned int _port)
00441 {
00442 int res;
00443
00444 sock = socket(AF_INET, SOCK_DGRAM, 0);
00445 if (sock == CL_INVALID_SOCKET) return false;
00446
00447 sockaddr_in addr;
00448 memset(&addr, 0, sizeof(sockaddr_in));
00449 addr.sin_family = AF_INET;
00450 addr.sin_addr.s_addr = INADDR_ANY;
00451 addr.sin_port = htons(_port);
00452
00453 res = ::bind(sock, (sockaddr *) &addr, sizeof(addr));
00454 if (res == -1) throw CL_Error(PRINT_SOCK_ERROR());
00455
00456 int enable = 1;
00457 res = setsockopt(
00458 sock,
00459 SOL_SOCKET,
00460 SO_BROADCAST,
00461 (const char *) &enable,
00462 sizeof(int));
00463
00464 if (res == -1)
00465 {
00466 cl_info(info_network, PRINT_SOCK_ERROR());
00467 closesocket(sock);
00468 return false;
00469 }
00470
00471
00472
00473 socklen_t len = sizeof(sockaddr_in);
00474 res = getsockname(sock, (sockaddr *) &addr, &len);
00475 if (res == -1) throw CL_Error(PRINT_SOCK_ERROR());
00476
00477 port = ntohs(addr.sin_port);
00478
00479 return true;
00480 }
00481
00482 bool CL_UniformUDPConnection::peek()
00483 {
00484 if (sock == CL_INVALID_SOCKET) return false;
00485
00486 fd_set rfds;
00487
00488 FD_ZERO(&rfds);
00489 FD_SET(sock, &rfds);
00490
00491 timeval timeout;
00492 memset(&timeout, 0, sizeof(timeval));
00493
00494 int retval = select(sock+1, &rfds, NULL, NULL, &timeout);
00495 if (retval == -1) return false;
00496
00497 return (retval > 0);
00498 }
00499
00500 CL_UDPConnectionPacket CL_UniformUDPConnection::receive()
00501 {
00502 char *receive_buf = new char[8096];
00503
00504 sockaddr_in addr;
00505 memset(&addr, 0, sizeof(sockaddr_in));
00506 addr.sin_family = AF_INET;
00507 socklen_t len_addr = sizeof(addr);
00508 int res = ::recvfrom(sock, receive_buf, 8096, 0, (sockaddr *) &addr, &len_addr);
00509 cl_assert(res != CL_SOCKET_ERROR);
00510
00511 CL_UDPConnectionPacket ret;
00512 ret.data = receive_buf;
00513 ret.size = res;
00514 ret.ip_addr = addr.sin_addr.s_addr;
00515 ret.port = ntohs(addr.sin_port);
00516
00517 return ret;
00518 }
00519
00520 void CL_UniformUDPConnection::send(CL_UDPConnectionPacket message)
00521 {
00522 sockaddr_in addr;
00523 memset(&addr, 0, sizeof(sockaddr_in));
00524 addr.sin_family = AF_INET;
00525 addr.sin_addr.s_addr = message.ip_addr;
00526 addr.sin_port = htons(message.port);
00527
00528 cl_assert(sock != CL_INVALID_SOCKET);
00529 cl_assert(message.size < 2000);
00530
00531 int res = ::sendto(
00532 sock,
00533 (char *) message.data,
00534 message.size,
00535 0,
00536 (sockaddr *) &addr,
00537 sizeof(sockaddr_in));
00538
00539 if (res == CL_SOCKET_ERROR)
00540 {
00541 cl_info(info_network, PRINT_SOCK_ERROR());
00542 }
00543
00544 cl_assert(res != -1);
00545 }
00546
00547 void CL_UniformUDPConnection::broadcast(CL_UDPConnectionPacket message)
00548 {
00549 cl_assert(sock != CL_INVALID_SOCKET);
00550 cl_assert(message.size < 2000);
00551
00552 sockaddr_in addr;
00553 memset(&addr, 0, sizeof(sockaddr_in));
00554 addr.sin_family = AF_INET;
00555 addr.sin_addr.s_addr = INADDR_BROADCAST;
00556 addr.sin_port = htons(message.port);
00557
00558 int res = ::sendto(
00559 sock,
00560 (char *) message.data,
00561 message.size,
00562 0,
00563 (sockaddr *) &addr,
00564 sizeof(sockaddr_in));
00565
00566 if (res == -1)
00567 {
00568 cl_info(info_network, PRINT_SOCK_ERROR());
00569 }
00570
00571 cl_assert(res != -1);
00572 }
00573
00574 unsigned int CL_UniformUDPConnection::get_port()
00575 {
00576 return port;
00577 }
00578
00579
00580
00581 #ifdef WIN32
00582 const char *get_win32_sock_error(DWORD err)
00583 {
00584 switch (err)
00585 {
00586 case WSAEACCES: return "Permission denied";
00587 case WSAEADDRINUSE: return "Address already in use";
00588 case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
00589 case WSAEAFNOSUPPORT: return "Address family not supported by protocol family";
00590 case WSAEALREADY: return "Operation already in progress";
00591 case WSAECONNABORTED: return "Software caused connection abort";
00592 case WSAECONNREFUSED: return "Connection refused";
00593 case WSAECONNRESET: return "Connection reset by peer";
00594 case WSAEDESTADDRREQ: return "Destination address required";
00595 case WSAEFAULT: return "Bad address";
00596 case WSAEHOSTDOWN: return "Host is down";
00597 case WSAEHOSTUNREACH: return "No route to host";
00598 case WSAEINPROGRESS: return "Operation now in progress";
00599 case WSAEINTR: return "Interrupted function call";
00600 case WSAEINVAL: return "Invalid argument";
00601 case WSAEISCONN: return "Socket is already connected";
00602 case WSAEMFILE: return "Too many open files";
00603 case WSAEMSGSIZE: return "Message too long";
00604 case WSAENETDOWN: return "Network is down";
00605 case WSAENETRESET: return "Network dropped connection on reset";
00606 case WSAENETUNREACH: return "Network is unreachable";
00607 case WSAENOBUFS: return "No buffer space available";
00608 case WSAENOPROTOOPT: return "Bad protocol option";
00609 case WSAENOTCONN: return "Socket is not connected";
00610 case WSAENOTSOCK: return "Socket operation on non-socket";
00611 case WSAEOPNOTSUPP: return "Operation not supported";
00612 case WSAEPFNOSUPPORT: return "Protocol family not supported";
00613 case WSAEPROCLIM: return "Too many processes";
00614 case WSAEPROTONOSUPPORT: return "Protocol not supported";
00615 case WSAEPROTOTYPE : return "Protocol wrong type for socket";
00616 case WSAESHUTDOWN: return "Cannot send after socket shutdown";
00617 case WSAESOCKTNOSUPPORT: return "Socket type not supported";
00618 case WSAETIMEDOUT: return "Connection timed out";
00619
00620 case WSAEWOULDBLOCK: return "Resource temporarily unavailable";
00621
00622 case WSANOTINITIALISED: return "Successful WSAStartup not yet performed";
00623 case WSANO_DATA: return "Valid name, no data record of requested type";
00624 case WSANO_RECOVERY: return "This is a non-recoverable error";
00625 case WSASYSNOTREADY: return "Network subsystem is unavailable";
00626 case WSATRY_AGAIN: return "Non-authoritative host not found";
00627 case WSAVERNOTSUPPORTED: return "WINSOCK.DLL version out of range";
00628 case WSAEDISCON: return "Graceful shutdown in progress";
00629 default: return "Unknown WSA error";
00630 };
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 }
00646 #endif