OLD | NEW |
| (Empty) |
1 /***************************************************************************** | |
2 Copyright (c) 2001 - 2010, The Board of Trustees of the University of Illinois. | |
3 All rights reserved. | |
4 | |
5 Redistribution and use in source and binary forms, with or without | |
6 modification, are permitted provided that the following conditions are | |
7 met: | |
8 | |
9 * Redistributions of source code must retain the above | |
10 copyright notice, this list of conditions and the | |
11 following disclaimer. | |
12 | |
13 * Redistributions in binary form must reproduce the | |
14 above copyright notice, this list of conditions | |
15 and the following disclaimer in the documentation | |
16 and/or other materials provided with the distribution. | |
17 | |
18 * Neither the name of the University of Illinois | |
19 nor the names of its contributors may be used to | |
20 endorse or promote products derived from this | |
21 software without specific prior written permission. | |
22 | |
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | |
24 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
25 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
26 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
34 *****************************************************************************/ | |
35 | |
36 /***************************************************************************** | |
37 written by | |
38 Yunhong Gu, last updated 07/25/2010 | |
39 *****************************************************************************/ | |
40 | |
41 | |
42 #ifndef WIN32 | |
43 #include <cstring> | |
44 #include <cerrno> | |
45 #include <unistd.h> | |
46 #else | |
47 #include <winsock2.h> | |
48 #include <ws2tcpip.h> | |
49 #ifdef LEGACY_WIN32 | |
50 #include <wspiapi.h> | |
51 #endif | |
52 #endif | |
53 # | |
54 #include <cmath> | |
55 #include "md5.h" | |
56 #include "common.h" | |
57 | |
58 uint64_t CTimer::s_ullCPUFrequency = CTimer::readCPUFrequency(); | |
59 #ifndef WIN32 | |
60 pthread_mutex_t CTimer::m_EventLock = PTHREAD_MUTEX_INITIALIZER; | |
61 pthread_cond_t CTimer::m_EventCond = PTHREAD_COND_INITIALIZER; | |
62 #else | |
63 pthread_mutex_t CTimer::m_EventLock = CreateMutex(NULL, false, NULL); | |
64 pthread_cond_t CTimer::m_EventCond = CreateEvent(NULL, false, false, NULL); | |
65 #endif | |
66 | |
67 CTimer::CTimer(): | |
68 m_ullSchedTime(), | |
69 m_TickCond(), | |
70 m_TickLock() | |
71 { | |
72 #ifndef WIN32 | |
73 pthread_mutex_init(&m_TickLock, NULL); | |
74 pthread_cond_init(&m_TickCond, NULL); | |
75 #else | |
76 m_TickLock = CreateMutex(NULL, false, NULL); | |
77 m_TickCond = CreateEvent(NULL, false, false, NULL); | |
78 #endif | |
79 } | |
80 | |
81 CTimer::~CTimer() | |
82 { | |
83 #ifndef WIN32 | |
84 pthread_mutex_destroy(&m_TickLock); | |
85 pthread_cond_destroy(&m_TickCond); | |
86 #else | |
87 CloseHandle(m_TickLock); | |
88 CloseHandle(m_TickCond); | |
89 #endif | |
90 } | |
91 | |
92 void CTimer::rdtsc(uint64_t &x) | |
93 { | |
94 #ifdef WIN32 | |
95 //HANDLE hCurThread = ::GetCurrentThread(); | |
96 //DWORD_PTR dwOldMask = ::SetThreadAffinityMask(hCurThread, 1); | |
97 BOOL ret = QueryPerformanceCounter((LARGE_INTEGER *)&x); | |
98 //SetThreadAffinityMask(hCurThread, dwOldMask); | |
99 | |
100 if (!ret) | |
101 x = getTime() * s_ullCPUFrequency; | |
102 | |
103 #elif IA32 | |
104 uint32_t lval, hval; | |
105 //asm volatile ("push %eax; push %ebx; push %ecx; push %edx"); | |
106 //asm volatile ("xor %eax, %eax; cpuid"); | |
107 asm volatile ("rdtsc" : "=a" (lval), "=d" (hval)); | |
108 //asm volatile ("pop %edx; pop %ecx; pop %ebx; pop %eax"); | |
109 x = hval; | |
110 x = (x << 32) | lval; | |
111 #elif IA64 | |
112 asm ("mov %0=ar.itc" : "=r"(x) :: "memory"); | |
113 #elif AMD64 | |
114 uint32_t lval, hval; | |
115 asm ("rdtsc" : "=a" (lval), "=d" (hval)); | |
116 x = hval; | |
117 x = (x << 32) | lval; | |
118 #else | |
119 // use system call to read time clock for other archs | |
120 timeval t; | |
121 gettimeofday(&t, 0); | |
122 x = (uint64_t)t.tv_sec * (uint64_t)1000000 + (uint64_t)t.tv_usec; | |
123 #endif | |
124 } | |
125 | |
126 uint64_t CTimer::readCPUFrequency() | |
127 { | |
128 #ifdef WIN32 | |
129 int64_t ccf; | |
130 if (QueryPerformanceFrequency((LARGE_INTEGER *)&ccf)) | |
131 return ccf / 1000000; | |
132 else | |
133 return 1; | |
134 #elif IA32 || IA64 || AMD64 | |
135 uint64_t t1, t2; | |
136 | |
137 rdtsc(t1); | |
138 timespec ts; | |
139 ts.tv_sec = 0; | |
140 ts.tv_nsec = 100000000; | |
141 nanosleep(&ts, NULL); | |
142 rdtsc(t2); | |
143 | |
144 // CPU clocks per microsecond | |
145 return (t2 - t1) / 100000; | |
146 #else | |
147 return 1; | |
148 #endif | |
149 } | |
150 | |
151 uint64_t CTimer::getCPUFrequency() | |
152 { | |
153 return s_ullCPUFrequency; | |
154 } | |
155 | |
156 void CTimer::sleep(const uint64_t& interval) | |
157 { | |
158 uint64_t t; | |
159 rdtsc(t); | |
160 | |
161 // sleep next "interval" time | |
162 sleepto(t + interval); | |
163 } | |
164 | |
165 void CTimer::sleepto(const uint64_t& nexttime) | |
166 { | |
167 // Use class member such that the method can be interrupted by others | |
168 m_ullSchedTime = nexttime; | |
169 | |
170 uint64_t t; | |
171 rdtsc(t); | |
172 | |
173 while (t < m_ullSchedTime) | |
174 { | |
175 #ifndef NO_BUSY_WAITING | |
176 #ifdef IA32 | |
177 __asm__ volatile ("pause; rep; nop; nop; nop; nop; nop;"); | |
178 #elif IA64 | |
179 __asm__ volatile ("nop 0; nop 0; nop 0; nop 0; nop 0;"); | |
180 #elif AMD64 | |
181 __asm__ volatile ("nop; nop; nop; nop; nop;"); | |
182 #endif | |
183 #else | |
184 #ifndef WIN32 | |
185 timeval now; | |
186 timespec timeout; | |
187 gettimeofday(&now, 0); | |
188 if (now.tv_usec < 990000) | |
189 { | |
190 timeout.tv_sec = now.tv_sec; | |
191 timeout.tv_nsec = (now.tv_usec + 10000) * 1000; | |
192 } | |
193 else | |
194 { | |
195 timeout.tv_sec = now.tv_sec + 1; | |
196 timeout.tv_nsec = (now.tv_usec + 10000 - 1000000) * 1000; | |
197 } | |
198 pthread_mutex_lock(&m_TickLock); | |
199 pthread_cond_timedwait(&m_TickCond, &m_TickLock, &timeout); | |
200 pthread_mutex_unlock(&m_TickLock); | |
201 #else | |
202 WaitForSingleObject(m_TickCond, 1); | |
203 #endif | |
204 #endif | |
205 | |
206 rdtsc(t); | |
207 } | |
208 } | |
209 | |
210 void CTimer::interrupt() | |
211 { | |
212 // schedule the sleepto time to the current CCs, so that it will stop | |
213 rdtsc(m_ullSchedTime); | |
214 | |
215 tick(); | |
216 } | |
217 | |
218 void CTimer::tick() | |
219 { | |
220 #ifndef WIN32 | |
221 pthread_cond_signal(&m_TickCond); | |
222 #else | |
223 SetEvent(m_TickCond); | |
224 #endif | |
225 } | |
226 | |
227 uint64_t CTimer::getTime() | |
228 { | |
229 //For Cygwin and other systems without microsecond level resolution, uncommen
t the following three lines | |
230 //uint64_t x; | |
231 //rdtsc(x); | |
232 //return x / s_ullCPUFrequency; | |
233 | |
234 #ifndef WIN32 | |
235 timeval t; | |
236 gettimeofday(&t, 0); | |
237 return t.tv_sec * 1000000ULL + t.tv_usec; | |
238 #else | |
239 LARGE_INTEGER ccf; | |
240 HANDLE hCurThread = ::GetCurrentThread(); | |
241 DWORD_PTR dwOldMask = ::SetThreadAffinityMask(hCurThread, 1); | |
242 if (QueryPerformanceFrequency(&ccf)) | |
243 { | |
244 LARGE_INTEGER cc; | |
245 if (QueryPerformanceCounter(&cc)) | |
246 { | |
247 SetThreadAffinityMask(hCurThread, dwOldMask); | |
248 return (cc.QuadPart * 1000000ULL / ccf.QuadPart); | |
249 } | |
250 } | |
251 | |
252 SetThreadAffinityMask(hCurThread, dwOldMask); | |
253 return GetTickCount() * 1000ULL; | |
254 #endif | |
255 } | |
256 | |
257 void CTimer::triggerEvent() | |
258 { | |
259 #ifndef WIN32 | |
260 pthread_cond_signal(&m_EventCond); | |
261 #else | |
262 SetEvent(m_EventCond); | |
263 #endif | |
264 } | |
265 | |
266 void CTimer::waitForEvent() | |
267 { | |
268 #ifndef WIN32 | |
269 timeval now; | |
270 timespec timeout; | |
271 gettimeofday(&now, 0); | |
272 if (now.tv_usec < 990000) | |
273 { | |
274 timeout.tv_sec = now.tv_sec; | |
275 timeout.tv_nsec = (now.tv_usec + 10000) * 1000; | |
276 } | |
277 else | |
278 { | |
279 timeout.tv_sec = now.tv_sec + 1; | |
280 timeout.tv_nsec = (now.tv_usec + 10000 - 1000000) * 1000; | |
281 } | |
282 pthread_mutex_lock(&m_EventLock); | |
283 pthread_cond_timedwait(&m_EventCond, &m_EventLock, &timeout); | |
284 pthread_mutex_unlock(&m_EventLock); | |
285 #else | |
286 WaitForSingleObject(m_EventCond, 1); | |
287 #endif | |
288 } | |
289 | |
290 void CTimer::sleep() | |
291 { | |
292 #ifndef WIN32 | |
293 usleep(10); | |
294 #else | |
295 Sleep(1); | |
296 #endif | |
297 } | |
298 | |
299 | |
300 // | |
301 // Automatically lock in constructor | |
302 CGuard::CGuard(pthread_mutex_t& lock): | |
303 m_Mutex(lock), | |
304 m_iLocked() | |
305 { | |
306 #ifndef WIN32 | |
307 m_iLocked = pthread_mutex_lock(&m_Mutex); | |
308 #else | |
309 m_iLocked = WaitForSingleObject(m_Mutex, INFINITE); | |
310 #endif | |
311 } | |
312 | |
313 // Automatically unlock in destructor | |
314 CGuard::~CGuard() | |
315 { | |
316 #ifndef WIN32 | |
317 if (0 == m_iLocked) | |
318 pthread_mutex_unlock(&m_Mutex); | |
319 #else | |
320 if (WAIT_FAILED != m_iLocked) | |
321 ReleaseMutex(m_Mutex); | |
322 #endif | |
323 } | |
324 | |
325 void CGuard::enterCS(pthread_mutex_t& lock) | |
326 { | |
327 #ifndef WIN32 | |
328 pthread_mutex_lock(&lock); | |
329 #else | |
330 WaitForSingleObject(lock, INFINITE); | |
331 #endif | |
332 } | |
333 | |
334 void CGuard::leaveCS(pthread_mutex_t& lock) | |
335 { | |
336 #ifndef WIN32 | |
337 pthread_mutex_unlock(&lock); | |
338 #else | |
339 ReleaseMutex(lock); | |
340 #endif | |
341 } | |
342 | |
343 void CGuard::createMutex(pthread_mutex_t& lock) | |
344 { | |
345 #ifndef WIN32 | |
346 pthread_mutex_init(&lock, NULL); | |
347 #else | |
348 lock = CreateMutex(NULL, false, NULL); | |
349 #endif | |
350 } | |
351 | |
352 void CGuard::releaseMutex(pthread_mutex_t& lock) | |
353 { | |
354 #ifndef WIN32 | |
355 pthread_mutex_destroy(&lock); | |
356 #else | |
357 CloseHandle(lock); | |
358 #endif | |
359 } | |
360 | |
361 void CGuard::createCond(pthread_cond_t& cond) | |
362 { | |
363 #ifndef WIN32 | |
364 pthread_cond_init(&cond, NULL); | |
365 #else | |
366 cond = CreateEvent(NULL, false, false, NULL); | |
367 #endif | |
368 } | |
369 | |
370 void CGuard::releaseCond(pthread_cond_t& cond) | |
371 { | |
372 #ifndef WIN32 | |
373 pthread_cond_destroy(&cond); | |
374 #else | |
375 CloseHandle(cond); | |
376 #endif | |
377 | |
378 } | |
379 | |
380 // | |
381 CUDTException::CUDTException(int major, int minor, int err): | |
382 m_iMajor(major), | |
383 m_iMinor(minor) | |
384 { | |
385 if (-1 == err) | |
386 #ifndef WIN32 | |
387 m_iErrno = errno; | |
388 #else | |
389 m_iErrno = GetLastError(); | |
390 #endif | |
391 else | |
392 m_iErrno = err; | |
393 } | |
394 | |
395 CUDTException::CUDTException(const CUDTException& e): | |
396 m_iMajor(e.m_iMajor), | |
397 m_iMinor(e.m_iMinor), | |
398 m_iErrno(e.m_iErrno), | |
399 m_strMsg() | |
400 { | |
401 } | |
402 | |
403 CUDTException::~CUDTException() | |
404 { | |
405 } | |
406 | |
407 const char* CUDTException::getErrorMessage() | |
408 { | |
409 // translate "Major:Minor" code into text message. | |
410 | |
411 switch (m_iMajor) | |
412 { | |
413 case 0: | |
414 m_strMsg = "Success"; | |
415 break; | |
416 | |
417 case 1: | |
418 m_strMsg = "Connection setup failure"; | |
419 | |
420 switch (m_iMinor) | |
421 { | |
422 case 1: | |
423 m_strMsg += ": connection time out"; | |
424 break; | |
425 | |
426 case 2: | |
427 m_strMsg += ": connection rejected"; | |
428 break; | |
429 | |
430 case 3: | |
431 m_strMsg += ": unable to create/configure UDP socket"; | |
432 break; | |
433 | |
434 case 4: | |
435 m_strMsg += ": abort for security reasons"; | |
436 break; | |
437 | |
438 default: | |
439 break; | |
440 } | |
441 | |
442 break; | |
443 | |
444 case 2: | |
445 switch (m_iMinor) | |
446 { | |
447 case 1: | |
448 m_strMsg = "Connection was broken"; | |
449 break; | |
450 | |
451 case 2: | |
452 m_strMsg = "Connection does not exist"; | |
453 break; | |
454 | |
455 default: | |
456 break; | |
457 } | |
458 | |
459 break; | |
460 | |
461 case 3: | |
462 m_strMsg = "System resource failure"; | |
463 | |
464 switch (m_iMinor) | |
465 { | |
466 case 1: | |
467 m_strMsg += ": unable to create new threads"; | |
468 break; | |
469 | |
470 case 2: | |
471 m_strMsg += ": unable to allocate buffers"; | |
472 break; | |
473 | |
474 default: | |
475 break; | |
476 } | |
477 | |
478 break; | |
479 | |
480 case 4: | |
481 m_strMsg = "File system failure"; | |
482 | |
483 switch (m_iMinor) | |
484 { | |
485 case 1: | |
486 m_strMsg += ": cannot seek read position"; | |
487 break; | |
488 | |
489 case 2: | |
490 m_strMsg += ": failure in read"; | |
491 break; | |
492 | |
493 case 3: | |
494 m_strMsg += ": cannot seek write position"; | |
495 break; | |
496 | |
497 case 4: | |
498 m_strMsg += ": failure in write"; | |
499 break; | |
500 | |
501 default: | |
502 break; | |
503 } | |
504 | |
505 break; | |
506 | |
507 case 5: | |
508 m_strMsg = "Operation not supported"; | |
509 | |
510 switch (m_iMinor) | |
511 { | |
512 case 1: | |
513 m_strMsg += ": Cannot do this operation on a BOUND socket"; | |
514 break; | |
515 | |
516 case 2: | |
517 m_strMsg += ": Cannot do this operation on a CONNECTED socket"; | |
518 break; | |
519 | |
520 case 3: | |
521 m_strMsg += ": Bad parameters"; | |
522 break; | |
523 | |
524 case 4: | |
525 m_strMsg += ": Invalid socket ID"; | |
526 break; | |
527 | |
528 case 5: | |
529 m_strMsg += ": Cannot do this operation on an UNBOUND socket"; | |
530 break; | |
531 | |
532 case 6: | |
533 m_strMsg += ": Socket is not in listening state"; | |
534 break; | |
535 | |
536 case 7: | |
537 m_strMsg += ": Listen/accept is not supported in rendezous connection
setup"; | |
538 break; | |
539 | |
540 case 8: | |
541 m_strMsg += ": Cannot call connect on UNBOUND socket in rendezvous co
nnection setup"; | |
542 break; | |
543 | |
544 case 9: | |
545 m_strMsg += ": This operation is not supported in SOCK_STREAM mode"; | |
546 break; | |
547 | |
548 case 10: | |
549 m_strMsg += ": This operation is not supported in SOCK_DGRAM mode"; | |
550 break; | |
551 | |
552 case 11: | |
553 m_strMsg += ": Another socket is already listening on the same port"; | |
554 break; | |
555 | |
556 case 12: | |
557 m_strMsg += ": Message is too large to send (it must be less than the
UDT send buffer size)"; | |
558 break; | |
559 | |
560 case 13: | |
561 m_strMsg += ": Invalid epoll ID"; | |
562 break; | |
563 | |
564 default: | |
565 break; | |
566 } | |
567 | |
568 break; | |
569 | |
570 case 6: | |
571 m_strMsg = "Non-blocking call failure"; | |
572 | |
573 switch (m_iMinor) | |
574 { | |
575 case 1: | |
576 m_strMsg += ": no buffer available for sending"; | |
577 break; | |
578 | |
579 case 2: | |
580 m_strMsg += ": no data available for reading"; | |
581 break; | |
582 | |
583 default: | |
584 break; | |
585 } | |
586 | |
587 break; | |
588 | |
589 case 7: | |
590 m_strMsg = "The peer side has signalled an error"; | |
591 | |
592 break; | |
593 | |
594 default: | |
595 m_strMsg = "Unknown error"; | |
596 } | |
597 | |
598 // Adding "errno" information | |
599 if ((0 != m_iMajor) && (0 < m_iErrno)) | |
600 { | |
601 m_strMsg += ": "; | |
602 #ifndef WIN32 | |
603 char errmsg[1024]; | |
604 if (strerror_r(m_iErrno, errmsg, 1024) == 0) | |
605 m_strMsg += errmsg; | |
606 #else | |
607 LPVOID lpMsgBuf; | |
608 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYST
EM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, m_iErrno, MAKELANGID(LANG_NEUTRAL, SUB
LANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL); | |
609 m_strMsg += (char*)lpMsgBuf; | |
610 LocalFree(lpMsgBuf); | |
611 #endif | |
612 } | |
613 | |
614 // period | |
615 #ifndef WIN32 | |
616 m_strMsg += "."; | |
617 #endif | |
618 | |
619 return m_strMsg.c_str(); | |
620 } | |
621 | |
622 int CUDTException::getErrorCode() const | |
623 { | |
624 return m_iMajor * 1000 + m_iMinor; | |
625 } | |
626 | |
627 void CUDTException::clear() | |
628 { | |
629 m_iMajor = 0; | |
630 m_iMinor = 0; | |
631 m_iErrno = 0; | |
632 } | |
633 | |
634 const int CUDTException::SUCCESS = 0; | |
635 const int CUDTException::ECONNSETUP = 1000; | |
636 const int CUDTException::ENOSERVER = 1001; | |
637 const int CUDTException::ECONNREJ = 1002; | |
638 const int CUDTException::ESOCKFAIL = 1003; | |
639 const int CUDTException::ESECFAIL = 1004; | |
640 const int CUDTException::ECONNFAIL = 2000; | |
641 const int CUDTException::ECONNLOST = 2001; | |
642 const int CUDTException::ENOCONN = 2002; | |
643 const int CUDTException::ERESOURCE = 3000; | |
644 const int CUDTException::ETHREAD = 3001; | |
645 const int CUDTException::ENOBUF = 3002; | |
646 const int CUDTException::EFILE = 4000; | |
647 const int CUDTException::EINVRDOFF = 4001; | |
648 const int CUDTException::ERDPERM = 4002; | |
649 const int CUDTException::EINVWROFF = 4003; | |
650 const int CUDTException::EWRPERM = 4004; | |
651 const int CUDTException::EINVOP = 5000; | |
652 const int CUDTException::EBOUNDSOCK = 5001; | |
653 const int CUDTException::ECONNSOCK = 5002; | |
654 const int CUDTException::EINVPARAM = 5003; | |
655 const int CUDTException::EINVSOCK = 5004; | |
656 const int CUDTException::EUNBOUNDSOCK = 5005; | |
657 const int CUDTException::ENOLISTEN = 5006; | |
658 const int CUDTException::ERDVNOSERV = 5007; | |
659 const int CUDTException::ERDVUNBOUND = 5008; | |
660 const int CUDTException::ESTREAMILL = 5009; | |
661 const int CUDTException::EDGRAMILL = 5010; | |
662 const int CUDTException::EDUPLISTEN = 5011; | |
663 const int CUDTException::ELARGEMSG = 5012; | |
664 const int CUDTException::EINVPOLLID = 5013; | |
665 const int CUDTException::EASYNCFAIL = 6000; | |
666 const int CUDTException::EASYNCSND = 6001; | |
667 const int CUDTException::EASYNCRCV = 6002; | |
668 const int CUDTException::EPEERERR = 7000; | |
669 const int CUDTException::EUNKNOWN = -1; | |
670 | |
671 | |
672 // | |
673 bool CIPAddress::ipcmp(const sockaddr* addr1, const sockaddr* addr2, const int&
ver) | |
674 { | |
675 if (AF_INET == ver) | |
676 { | |
677 sockaddr_in* a1 = (sockaddr_in*)addr1; | |
678 sockaddr_in* a2 = (sockaddr_in*)addr2; | |
679 | |
680 if ((a1->sin_port == a2->sin_port) && (a1->sin_addr.s_addr == a2->sin_addr
.s_addr)) | |
681 return true; | |
682 } | |
683 else | |
684 { | |
685 sockaddr_in6* a1 = (sockaddr_in6*)addr1; | |
686 sockaddr_in6* a2 = (sockaddr_in6*)addr2; | |
687 | |
688 if (a1->sin6_port == a2->sin6_port) | |
689 { | |
690 for (int i = 0; i < 16; ++ i) | |
691 if (*((char*)&(a1->sin6_addr) + i) != *((char*)&(a2->sin6_addr) + i)
) | |
692 return false; | |
693 | |
694 return true; | |
695 } | |
696 } | |
697 | |
698 return false; | |
699 } | |
700 | |
701 void CIPAddress::ntop(const sockaddr* addr, uint32_t ip[4], const int& ver) | |
702 { | |
703 if (AF_INET == ver) | |
704 { | |
705 sockaddr_in* a = (sockaddr_in*)addr; | |
706 ip[0] = a->sin_addr.s_addr; | |
707 } | |
708 else | |
709 { | |
710 sockaddr_in6* a = (sockaddr_in6*)addr; | |
711 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]; | |
712 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]; | |
713 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]; | |
714 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]; | |
715 } | |
716 } | |
717 | |
718 void CIPAddress::pton(sockaddr* addr, const uint32_t ip[4], const int& ver) | |
719 { | |
720 if (AF_INET == ver) | |
721 { | |
722 sockaddr_in* a = (sockaddr_in*)addr; | |
723 a->sin_addr.s_addr = ip[0]; | |
724 } | |
725 else | |
726 { | |
727 sockaddr_in6* a = (sockaddr_in6*)addr; | |
728 for (int i = 0; i < 4; ++ i) | |
729 { | |
730 a->sin6_addr.s6_addr[i * 4] = ip[i] & 0xFF; | |
731 a->sin6_addr.s6_addr[i * 4 + 1] = (unsigned char)((ip[i] & 0xFF00) >> 8
); | |
732 a->sin6_addr.s6_addr[i * 4 + 2] = (unsigned char)((ip[i] & 0xFF0000) >>
16); | |
733 a->sin6_addr.s6_addr[i * 4 + 3] = (unsigned char)((ip[i] & 0xFF000000)
>> 24); | |
734 } | |
735 } | |
736 } | |
737 | |
738 // | |
739 void CMD5::compute(const char* input, unsigned char result[16]) | |
740 { | |
741 md5_state_t state; | |
742 | |
743 md5_init(&state); | |
744 md5_append(&state, (const md5_byte_t *)input, strlen(input)); | |
745 md5_finish(&state, result); | |
746 } | |
OLD | NEW |