Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(219)

Side by Side Diff: net/third_party/udt/src/common.cpp

Issue 6708091: Remove UDT. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/third_party/udt/src/common.h ('k') | net/third_party/udt/src/core.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 }
OLDNEW
« no previous file with comments | « net/third_party/udt/src/common.h ('k') | net/third_party/udt/src/core.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698