00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef WIN32
00043 #include <cstring>
00044 #include <cerrno>
00045 #include <unistd.h>
00046 #ifdef OSX
00047 #include <mach/mach_time.h>
00048 #endif
00049 #else
00050 #include <winsock2.h>
00051 #include <ws2tcpip.h>
00052 #ifdef LEGACY_WIN32
00053 #include <wspiapi.h>
00054 #endif
00055 #endif
00056
00057 #include <cmath>
00058 #include "md5.h"
00059 #include "common.h"
00060
00061 bool CTimer::m_bUseMicroSecond = false;
00062 uint64_t CTimer::s_ullCPUFrequency = CTimer::readCPUFrequency();
00063 #ifndef WIN32
00064 pthread_mutex_t CTimer::m_EventLock = PTHREAD_MUTEX_INITIALIZER;
00065 pthread_cond_t CTimer::m_EventCond = PTHREAD_COND_INITIALIZER;
00066 #else
00067 pthread_mutex_t CTimer::m_EventLock = CreateMutex(NULL, false, NULL);
00068 pthread_cond_t CTimer::m_EventCond = CreateEvent(NULL, false, false, NULL);
00069 #endif
00070
00071 CTimer::CTimer():
00072 m_ullSchedTime(),
00073 m_TickCond(),
00074 m_TickLock()
00075 {
00076 #ifndef WIN32
00077 pthread_mutex_init(&m_TickLock, NULL);
00078 pthread_cond_init(&m_TickCond, NULL);
00079 #else
00080 m_TickLock = CreateMutex(NULL, false, NULL);
00081 m_TickCond = CreateEvent(NULL, false, false, NULL);
00082 #endif
00083 }
00084
00085 CTimer::~CTimer()
00086 {
00087 #ifndef WIN32
00088 pthread_mutex_destroy(&m_TickLock);
00089 pthread_cond_destroy(&m_TickCond);
00090 #else
00091 CloseHandle(m_TickLock);
00092 CloseHandle(m_TickCond);
00093 #endif
00094 }
00095
00096 void CTimer::rdtsc(uint64_t &x)
00097 {
00098 if (m_bUseMicroSecond)
00099 {
00100 x = getTime();
00101 return;
00102 }
00103
00104 #ifdef IA32
00105 uint32_t lval, hval;
00106
00107
00108 asm volatile ("rdtsc" : "=a" (lval), "=d" (hval));
00109
00110 x = hval;
00111 x = (x << 32) | lval;
00112 #elif defined(IA64)
00113 asm ("mov %0=ar.itc" : "=r"(x) :: "memory");
00114 #elif defined(AMD64)
00115 uint32_t lval, hval;
00116 asm ("rdtsc" : "=a" (lval), "=d" (hval));
00117 x = hval;
00118 x = (x << 32) | lval;
00119 #elif defined(WIN32)
00120
00121
00122 BOOL ret = QueryPerformanceCounter((LARGE_INTEGER *)&x);
00123
00124 if (!ret)
00125 x = getTime() * s_ullCPUFrequency;
00126 #elif defined(OSX)
00127 x = mach_absolute_time();
00128 #else
00129
00130 x = getTime();
00131 #endif
00132 }
00133
00134 uint64_t CTimer::readCPUFrequency()
00135 {
00136 uint64_t frequency = 1;
00137
00138 #if defined(IA32) || defined(IA64) || defined(AMD64)
00139 uint64_t t1, t2;
00140
00141 rdtsc(t1);
00142 timespec ts;
00143 ts.tv_sec = 0;
00144 ts.tv_nsec = 100000000;
00145 nanosleep(&ts, NULL);
00146 rdtsc(t2);
00147
00148
00149 frequency = (t2 - t1) / 100000;
00150 #elif defined(WIN32)
00151 int64_t ccf;
00152 if (QueryPerformanceFrequency((LARGE_INTEGER *)&ccf))
00153 frequency = ccf / 1000000;
00154 #elif defined(OSX)
00155 mach_timebase_info_data_t info;
00156 mach_timebase_info(&info);
00157 frequency = info.denom * 1000ULL / info.numer;
00158 #endif
00159
00160
00161 if (frequency < 10)
00162 {
00163 frequency = 1;
00164 m_bUseMicroSecond = true;
00165 }
00166 return frequency;
00167 }
00168
00169 uint64_t CTimer::getCPUFrequency()
00170 {
00171 return s_ullCPUFrequency;
00172 }
00173
00174 void CTimer::sleep(uint64_t interval)
00175 {
00176 uint64_t t;
00177 rdtsc(t);
00178
00179
00180 sleepto(t + interval);
00181 }
00182
00183 void CTimer::sleepto(uint64_t nexttime)
00184 {
00185
00186 m_ullSchedTime = nexttime;
00187
00188 uint64_t t;
00189 rdtsc(t);
00190
00191 while (t < m_ullSchedTime)
00192 {
00193 #ifndef NO_BUSY_WAITING
00194 #ifdef IA32
00195 __asm__ volatile ("pause; rep; nop; nop; nop; nop; nop;");
00196 #elif IA64
00197 __asm__ volatile ("nop 0; nop 0; nop 0; nop 0; nop 0;");
00198 #elif AMD64
00199 __asm__ volatile ("nop; nop; nop; nop; nop;");
00200 #endif
00201 #else
00202 #ifndef WIN32
00203 timeval now;
00204 timespec timeout;
00205 gettimeofday(&now, 0);
00206 if (now.tv_usec < 990000)
00207 {
00208 timeout.tv_sec = now.tv_sec;
00209 timeout.tv_nsec = (now.tv_usec + 10000) * 1000;
00210 }
00211 else
00212 {
00213 timeout.tv_sec = now.tv_sec + 1;
00214 timeout.tv_nsec = (now.tv_usec + 10000 - 1000000) * 1000;
00215 }
00216 pthread_mutex_lock(&m_TickLock);
00217 pthread_cond_timedwait(&m_TickCond, &m_TickLock, &timeout);
00218 pthread_mutex_unlock(&m_TickLock);
00219 #else
00220 WaitForSingleObject(m_TickCond, 1);
00221 #endif
00222 #endif
00223
00224 rdtsc(t);
00225 }
00226 }
00227
00228 void CTimer::interrupt()
00229 {
00230
00231 rdtsc(m_ullSchedTime);
00232 tick();
00233 }
00234
00235 void CTimer::tick()
00236 {
00237 #ifndef WIN32
00238 pthread_cond_signal(&m_TickCond);
00239 #else
00240 SetEvent(m_TickCond);
00241 #endif
00242 }
00243
00244 uint64_t CTimer::getTime()
00245 {
00246
00247
00248
00249
00250
00251
00252 #ifndef WIN32
00253 timeval t;
00254 gettimeofday(&t, 0);
00255 return t.tv_sec * 1000000ULL + t.tv_usec;
00256 #else
00257 LARGE_INTEGER ccf;
00258 HANDLE hCurThread = ::GetCurrentThread();
00259 DWORD_PTR dwOldMask = ::SetThreadAffinityMask(hCurThread, 1);
00260 if (QueryPerformanceFrequency(&ccf))
00261 {
00262 LARGE_INTEGER cc;
00263 if (QueryPerformanceCounter(&cc))
00264 {
00265 SetThreadAffinityMask(hCurThread, dwOldMask);
00266 return (cc.QuadPart * 1000000ULL / ccf.QuadPart);
00267 }
00268 }
00269
00270 SetThreadAffinityMask(hCurThread, dwOldMask);
00271 return GetTickCount() * 1000ULL;
00272 #endif
00273 }
00274
00275 void CTimer::triggerEvent()
00276 {
00277 #ifndef WIN32
00278 pthread_cond_signal(&m_EventCond);
00279 #else
00280 SetEvent(m_EventCond);
00281 #endif
00282 }
00283
00284 void CTimer::waitForEvent()
00285 {
00286 #ifndef WIN32
00287 timeval now;
00288 timespec timeout;
00289 gettimeofday(&now, 0);
00290 if (now.tv_usec < 990000)
00291 {
00292 timeout.tv_sec = now.tv_sec;
00293 timeout.tv_nsec = (now.tv_usec + 10000) * 1000;
00294 }
00295 else
00296 {
00297 timeout.tv_sec = now.tv_sec + 1;
00298 timeout.tv_nsec = (now.tv_usec + 10000 - 1000000) * 1000;
00299 }
00300 pthread_mutex_lock(&m_EventLock);
00301 pthread_cond_timedwait(&m_EventCond, &m_EventLock, &timeout);
00302 pthread_mutex_unlock(&m_EventLock);
00303 #else
00304 WaitForSingleObject(m_EventCond, 1);
00305 #endif
00306 }
00307
00308 void CTimer::sleep()
00309 {
00310 #ifndef WIN32
00311 usleep(10);
00312 #else
00313 Sleep(1);
00314 #endif
00315 }
00316
00317
00318
00319
00320 CGuard::CGuard(pthread_mutex_t& lock):
00321 m_Mutex(lock),
00322 m_iLocked()
00323 {
00324 #ifndef WIN32
00325 m_iLocked = pthread_mutex_lock(&m_Mutex);
00326 #else
00327 m_iLocked = WaitForSingleObject(m_Mutex, INFINITE);
00328 #endif
00329 }
00330
00331
00332 CGuard::~CGuard()
00333 {
00334 #ifndef WIN32
00335 if (0 == m_iLocked)
00336 pthread_mutex_unlock(&m_Mutex);
00337 #else
00338 if (WAIT_FAILED != m_iLocked)
00339 ReleaseMutex(m_Mutex);
00340 #endif
00341 }
00342
00343 void CGuard::enterCS(pthread_mutex_t& lock)
00344 {
00345 #ifndef WIN32
00346 pthread_mutex_lock(&lock);
00347 #else
00348 WaitForSingleObject(lock, INFINITE);
00349 #endif
00350 }
00351
00352 void CGuard::leaveCS(pthread_mutex_t& lock)
00353 {
00354 #ifndef WIN32
00355 pthread_mutex_unlock(&lock);
00356 #else
00357 ReleaseMutex(lock);
00358 #endif
00359 }
00360
00361 void CGuard::createMutex(pthread_mutex_t& lock)
00362 {
00363 #ifndef WIN32
00364 pthread_mutex_init(&lock, NULL);
00365 #else
00366 lock = CreateMutex(NULL, false, NULL);
00367 #endif
00368 }
00369
00370 void CGuard::releaseMutex(pthread_mutex_t& lock)
00371 {
00372 #ifndef WIN32
00373 pthread_mutex_destroy(&lock);
00374 #else
00375 CloseHandle(lock);
00376 #endif
00377 }
00378
00379 void CGuard::createCond(pthread_cond_t& cond)
00380 {
00381 #ifndef WIN32
00382 pthread_cond_init(&cond, NULL);
00383 #else
00384 cond = CreateEvent(NULL, false, false, NULL);
00385 #endif
00386 }
00387
00388 void CGuard::releaseCond(pthread_cond_t& cond)
00389 {
00390 #ifndef WIN32
00391 pthread_cond_destroy(&cond);
00392 #else
00393 CloseHandle(cond);
00394 #endif
00395
00396 }
00397
00398
00399 CUDTException::CUDTException(int major, int minor, int err):
00400 m_iMajor(major),
00401 m_iMinor(minor)
00402 {
00403 if (-1 == err)
00404 #ifndef WIN32
00405 m_iErrno = errno;
00406 #else
00407 m_iErrno = GetLastError();
00408 #endif
00409 else
00410 m_iErrno = err;
00411 }
00412
00413 CUDTException::CUDTException(const CUDTException& e):
00414 m_iMajor(e.m_iMajor),
00415 m_iMinor(e.m_iMinor),
00416 m_iErrno(e.m_iErrno),
00417 m_strMsg()
00418 {
00419 }
00420
00421 CUDTException::~CUDTException()
00422 {
00423 }
00424
00425 const char* CUDTException::getErrorMessage()
00426 {
00427
00428
00429 switch (m_iMajor)
00430 {
00431 case 0:
00432 m_strMsg = "Success";
00433 break;
00434
00435 case 1:
00436 m_strMsg = "Connection setup failure";
00437
00438 switch (m_iMinor)
00439 {
00440 case 1:
00441 m_strMsg += ": connection time out";
00442 break;
00443
00444 case 2:
00445 m_strMsg += ": connection rejected";
00446 break;
00447
00448 case 3:
00449 m_strMsg += ": unable to create/configure UDP socket";
00450 break;
00451
00452 case 4:
00453 m_strMsg += ": abort for security reasons";
00454 break;
00455
00456 default:
00457 break;
00458 }
00459
00460 break;
00461
00462 case 2:
00463 switch (m_iMinor)
00464 {
00465 case 1:
00466 m_strMsg = "Connection was broken";
00467 break;
00468
00469 case 2:
00470 m_strMsg = "Connection does not exist";
00471 break;
00472
00473 default:
00474 break;
00475 }
00476
00477 break;
00478
00479 case 3:
00480 m_strMsg = "System resource failure";
00481
00482 switch (m_iMinor)
00483 {
00484 case 1:
00485 m_strMsg += ": unable to create new threads";
00486 break;
00487
00488 case 2:
00489 m_strMsg += ": unable to allocate buffers";
00490 break;
00491
00492 default:
00493 break;
00494 }
00495
00496 break;
00497
00498 case 4:
00499 m_strMsg = "File system failure";
00500
00501 switch (m_iMinor)
00502 {
00503 case 1:
00504 m_strMsg += ": cannot seek read position";
00505 break;
00506
00507 case 2:
00508 m_strMsg += ": failure in read";
00509 break;
00510
00511 case 3:
00512 m_strMsg += ": cannot seek write position";
00513 break;
00514
00515 case 4:
00516 m_strMsg += ": failure in write";
00517 break;
00518
00519 default:
00520 break;
00521 }
00522
00523 break;
00524
00525 case 5:
00526 m_strMsg = "Operation not supported";
00527
00528 switch (m_iMinor)
00529 {
00530 case 1:
00531 m_strMsg += ": Cannot do this operation on a BOUND socket";
00532 break;
00533
00534 case 2:
00535 m_strMsg += ": Cannot do this operation on a CONNECTED socket";
00536 break;
00537
00538 case 3:
00539 m_strMsg += ": Bad parameters";
00540 break;
00541
00542 case 4:
00543 m_strMsg += ": Invalid socket ID";
00544 break;
00545
00546 case 5:
00547 m_strMsg += ": Cannot do this operation on an UNBOUND socket";
00548 break;
00549
00550 case 6:
00551 m_strMsg += ": Socket is not in listening state";
00552 break;
00553
00554 case 7:
00555 m_strMsg += ": Listen/accept is not supported in rendezous connection setup";
00556 break;
00557
00558 case 8:
00559 m_strMsg += ": Cannot call connect on UNBOUND socket in rendezvous connection setup";
00560 break;
00561
00562 case 9:
00563 m_strMsg += ": This operation is not supported in SOCK_STREAM mode";
00564 break;
00565
00566 case 10:
00567 m_strMsg += ": This operation is not supported in SOCK_DGRAM mode";
00568 break;
00569
00570 case 11:
00571 m_strMsg += ": Another socket is already listening on the same port";
00572 break;
00573
00574 case 12:
00575 m_strMsg += ": Message is too large to send (it must be less than the UDT send buffer size)";
00576 break;
00577
00578 case 13:
00579 m_strMsg += ": Invalid epoll ID";
00580 break;
00581
00582 default:
00583 break;
00584 }
00585
00586 break;
00587
00588 case 6:
00589 m_strMsg = "Non-blocking call failure";
00590
00591 switch (m_iMinor)
00592 {
00593 case 1:
00594 m_strMsg += ": no buffer available for sending";
00595 break;
00596
00597 case 2:
00598 m_strMsg += ": no data available for reading";
00599 break;
00600
00601 default:
00602 break;
00603 }
00604
00605 break;
00606
00607 case 7:
00608 m_strMsg = "The peer side has signalled an error";
00609
00610 break;
00611
00612 default:
00613 m_strMsg = "Unknown error";
00614 }
00615
00616
00617 if ((0 != m_iMajor) && (0 < m_iErrno))
00618 {
00619 m_strMsg += ": ";
00620 #ifndef WIN32
00621 char errmsg[1024];
00622 if (strerror_r(m_iErrno, errmsg, 1024) == 0)
00623 m_strMsg += errmsg;
00624 #else
00625 LPVOID lpMsgBuf;
00626 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, m_iErrno, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
00627 m_strMsg += (char*)lpMsgBuf;
00628 LocalFree(lpMsgBuf);
00629 #endif
00630 }
00631
00632
00633 #ifndef WIN32
00634 m_strMsg += ".";
00635 #endif
00636
00637 return m_strMsg.c_str();
00638 }
00639
00640 int CUDTException::getErrorCode() const
00641 {
00642 return m_iMajor * 1000 + m_iMinor;
00643 }
00644
00645 void CUDTException::clear()
00646 {
00647 m_iMajor = 0;
00648 m_iMinor = 0;
00649 m_iErrno = 0;
00650 }
00651
00652 const int CUDTException::SUCCESS = 0;
00653 const int CUDTException::ECONNSETUP = 1000;
00654 const int CUDTException::ENOSERVER = 1001;
00655 const int CUDTException::ECONNREJ = 1002;
00656 const int CUDTException::ESOCKFAIL = 1003;
00657 const int CUDTException::ESECFAIL = 1004;
00658 const int CUDTException::ECONNFAIL = 2000;
00659 const int CUDTException::ECONNLOST = 2001;
00660 const int CUDTException::ENOCONN = 2002;
00661 const int CUDTException::ERESOURCE = 3000;
00662 const int CUDTException::ETHREAD = 3001;
00663 const int CUDTException::ENOBUF = 3002;
00664 const int CUDTException::EFILE = 4000;
00665 const int CUDTException::EINVRDOFF = 4001;
00666 const int CUDTException::ERDPERM = 4002;
00667 const int CUDTException::EINVWROFF = 4003;
00668 const int CUDTException::EWRPERM = 4004;
00669 const int CUDTException::EINVOP = 5000;
00670 const int CUDTException::EBOUNDSOCK = 5001;
00671 const int CUDTException::ECONNSOCK = 5002;
00672 const int CUDTException::EINVPARAM = 5003;
00673 const int CUDTException::EINVSOCK = 5004;
00674 const int CUDTException::EUNBOUNDSOCK = 5005;
00675 const int CUDTException::ENOLISTEN = 5006;
00676 const int CUDTException::ERDVNOSERV = 5007;
00677 const int CUDTException::ERDVUNBOUND = 5008;
00678 const int CUDTException::ESTREAMILL = 5009;
00679 const int CUDTException::EDGRAMILL = 5010;
00680 const int CUDTException::EDUPLISTEN = 5011;
00681 const int CUDTException::ELARGEMSG = 5012;
00682 const int CUDTException::EINVPOLLID = 5013;
00683 const int CUDTException::EASYNCFAIL = 6000;
00684 const int CUDTException::EASYNCSND = 6001;
00685 const int CUDTException::EASYNCRCV = 6002;
00686 const int CUDTException::ETIMEOUT = 6003;
00687 const int CUDTException::EPEERERR = 7000;
00688 const int CUDTException::EUNKNOWN = -1;
00689
00690
00691
00692 bool CIPAddress::ipcmp(const sockaddr* addr1, const sockaddr* addr2, int ver)
00693 {
00694 if (AF_INET == ver)
00695 {
00696 sockaddr_in* a1 = (sockaddr_in*)addr1;
00697 sockaddr_in* a2 = (sockaddr_in*)addr2;
00698
00699 if ((a1->sin_port == a2->sin_port) && (a1->sin_addr.s_addr == a2->sin_addr.s_addr))
00700 return true;
00701 }
00702 else
00703 {
00704 sockaddr_in6* a1 = (sockaddr_in6*)addr1;
00705 sockaddr_in6* a2 = (sockaddr_in6*)addr2;
00706
00707 if (a1->sin6_port == a2->sin6_port)
00708 {
00709 for (int i = 0; i < 16; ++ i)
00710 if (*((char*)&(a1->sin6_addr) + i) != *((char*)&(a2->sin6_addr) + i))
00711 return false;
00712
00713 return true;
00714 }
00715 }
00716
00717 return false;
00718 }
00719
00720 void CIPAddress::ntop(const sockaddr* addr, uint32_t ip[4], int ver)
00721 {
00722 if (AF_INET == ver)
00723 {
00724 sockaddr_in* a = (sockaddr_in*)addr;
00725 ip[0] = a->sin_addr.s_addr;
00726 }
00727 else
00728 {
00729 sockaddr_in6* a = (sockaddr_in6*)addr;
00730 ip[3] = (a->sin6_addr.s6_addr[15] << 24) + (a->sin6_addr.s6_addr[14] << 16) + (a->sin6_addr.s6_addr[13] << 8) + a->sin6_addr.s6_addr[12];
00731 ip[2] = (a->sin6_addr.s6_addr[11] << 24) + (a->sin6_addr.s6_addr[10] << 16) + (a->sin6_addr.s6_addr[9] << 8) + a->sin6_addr.s6_addr[8];
00732 ip[1] = (a->sin6_addr.s6_addr[7] << 24) + (a->sin6_addr.s6_addr[6] << 16) + (a->sin6_addr.s6_addr[5] << 8) + a->sin6_addr.s6_addr[4];
00733 ip[0] = (a->sin6_addr.s6_addr[3] << 24) + (a->sin6_addr.s6_addr[2] << 16) + (a->sin6_addr.s6_addr[1] << 8) + a->sin6_addr.s6_addr[0];
00734 }
00735 }
00736
00737 void CIPAddress::pton(sockaddr* addr, const uint32_t ip[4], int ver)
00738 {
00739 if (AF_INET == ver)
00740 {
00741 sockaddr_in* a = (sockaddr_in*)addr;
00742 a->sin_addr.s_addr = ip[0];
00743 }
00744 else
00745 {
00746 sockaddr_in6* a = (sockaddr_in6*)addr;
00747 for (int i = 0; i < 4; ++ i)
00748 {
00749 a->sin6_addr.s6_addr[i * 4] = ip[i] & 0xFF;
00750 a->sin6_addr.s6_addr[i * 4 + 1] = (unsigned char)((ip[i] & 0xFF00) >> 8);
00751 a->sin6_addr.s6_addr[i * 4 + 2] = (unsigned char)((ip[i] & 0xFF0000) >> 16);
00752 a->sin6_addr.s6_addr[i * 4 + 3] = (unsigned char)((ip[i] & 0xFF000000) >> 24);
00753 }
00754 }
00755 }
00756
00757
00758 void CMD5::compute(const char* input, unsigned char result[16])
00759 {
00760 md5_state_t state;
00761
00762 md5_init(&state);
00763 md5_append(&state, (const md5_byte_t *)input, strlen(input));
00764 md5_finish(&state, result);
00765 }