common.cpp

00001 /*****************************************************************************
00002 Copyright (c) 2001 - 2010, The Board of Trustees of the University of Illinois.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are
00007 met:
00008 
00009 * Redistributions of source code must retain the above
00010   copyright notice, this list of conditions and the
00011   following disclaimer.
00012 
00013 * Redistributions in binary form must reproduce the
00014   above copyright notice, this list of conditions
00015   and the following disclaimer in the documentation
00016   and/or other materials provided with the distribution.
00017 
00018 * Neither the name of the University of Illinois
00019   nor the names of its contributors may be used to
00020   endorse or promote products derived from this
00021   software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00024 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
00025 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00026 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00027 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00028 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00029 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00030 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00031 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00032 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00033 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 *****************************************************************************/
00035 
00036 /*****************************************************************************
00037 written by
00038    Yunhong Gu, last updated 07/25/2010
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       //asm volatile ("push %eax; push %ebx; push %ecx; push %edx");
00107       //asm volatile ("xor %eax, %eax; cpuid");
00108       asm volatile ("rdtsc" : "=a" (lval), "=d" (hval));
00109       //asm volatile ("pop %edx; pop %ecx; pop %ebx; pop %eax");
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       //HANDLE hCurThread = ::GetCurrentThread(); 
00121       //DWORD_PTR dwOldMask = ::SetThreadAffinityMask(hCurThread, 1); 
00122       BOOL ret = QueryPerformanceCounter((LARGE_INTEGER *)&x);
00123       //SetThreadAffinityMask(hCurThread, dwOldMask);
00124       if (!ret)
00125          x = getTime() * s_ullCPUFrequency;
00126    #elif defined(OSX)
00127       x = mach_absolute_time();
00128    #else
00129       // use system call to read time clock for other archs
00130       x = getTime();
00131    #endif
00132 }
00133 
00134 uint64_t CTimer::readCPUFrequency()
00135 {
00136    uint64_t frequency = 1;  // 1 tick per microsecond.
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       // CPU clocks per microsecond
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    // Fall back to microsecond if the resolution is not high enough.
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    // sleep next "interval" time
00180    sleepto(t + interval);
00181 }
00182 
00183 void CTimer::sleepto(uint64_t nexttime)
00184 {
00185    // Use class member such that the method can be interrupted by others
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    // schedule the sleepto time to the current CCs, so that it will stop
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    //For Cygwin and other systems without microsecond level resolution, uncomment the following three lines
00247    //uint64_t x;
00248    //rdtsc(x);
00249    //return x / s_ullCPUFrequency;
00250    //Specific fix may be necessary if rdtsc is not available either.
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 // Automatically lock in constructor
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 // Automatically unlock in destructor
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    // translate "Major:Minor" code into text message.
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    // Adding "errno" information
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    // period
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 }

Generated on 9 Feb 2013 for barchart-udt-core-2.2.2 by  doxygen 1.6.1