1 | #include "StdAfx.h"
|
2 |
|
3 | #include "utypes.h"
|
4 | #include <assert.h>
|
5 | #include <stdlib.h>
|
6 |
|
7 | #ifdef WIN32
|
8 |
|
9 | #define WIN32_LEAN_AND_MEAN
|
10 | #include <windows.h>
|
11 | #include <winsock2.h>
|
12 | #include <ws2tcpip.h>
|
13 |
|
14 | typedef ULONGLONG (WINAPI GetTickCount64Proc)(void);
|
15 | static GetTickCount64Proc *pt2GetTickCount64;
|
16 | static GetTickCount64Proc *pt2RealGetTickCount;
|
17 |
|
18 | static uint64 startPerformanceCounter;
|
19 | static uint64 startGetTickCount;
|
20 |
|
21 | static double counterPerMicrosecond;
|
22 |
|
23 | uint64 UTGetTickCount64()
|
24 | {
|
25 | if (pt2GetTickCount64) {
|
26 | return pt2GetTickCount64();
|
27 | }
|
28 | if (pt2RealGetTickCount) {
|
29 | uint64 v = pt2RealGetTickCount();
|
30 |
|
31 | return (DWORD)v | ((v >> 0x18) & 0xFFFFFFFF00000000);
|
32 | }
|
33 | return (uint64)GetTickCount();
|
34 | }
|
35 |
|
36 | void Time_Initialize()
|
37 | {
|
38 | HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
|
39 | pt2GetTickCount64 = (GetTickCount64Proc*)GetProcAddress(kernel32, "GetTickCount64");
|
40 |
|
41 | pt2RealGetTickCount = (GetTickCount64Proc*)GetProcAddress(kernel32, "GetTickCount");
|
42 |
|
43 | uint64 frequency;
|
44 | QueryPerformanceCounter((LARGE_INTEGER*)&startPerformanceCounter);
|
45 | QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
|
46 | counterPerMicrosecond = (double)frequency / 1000000.0f;
|
47 | startGetTickCount = UTGetTickCount64();
|
48 | }
|
49 |
|
50 | int64 abs64(int64 x) { return x < 0 ? -x : x; }
|
51 |
|
52 | static uint64 GetMicroseconds()
|
53 | {
|
54 | static bool time_init = false;
|
55 | if (!time_init) {
|
56 | time_init = true;
|
57 | Time_Initialize();
|
58 | }
|
59 |
|
60 | uint64 counter;
|
61 | uint64 tick;
|
62 |
|
63 | QueryPerformanceCounter((LARGE_INTEGER*) &counter);
|
64 | tick = UTGetTickCount64();
|
65 |
|
66 |
|
67 |
|
68 | int64 ret = (int64)(((int64)counter - (int64)startPerformanceCounter) / counterPerMicrosecond);
|
69 |
|
70 |
|
71 | int64 tick_diff = tick - startGetTickCount;
|
72 | if (abs64(ret / 100000 - tick_diff / 100) > 10) {
|
73 | startPerformanceCounter -= (uint64)((int64)(tick_diff * 1000 - ret) * counterPerMicrosecond);
|
74 | ret = (int64)((counter - startPerformanceCounter) / counterPerMicrosecond);
|
75 | }
|
76 | return ret;
|
77 | }
|
78 |
|
79 | #else //!WIN32
|
80 |
|
81 | #include <time.h>
|
82 | #include <sys/time.h> // Linux needs both time.h and sys/time.h
|
83 | #include <stdlib.h>
|
84 |
|
85 | #include <unistd.h>
|
86 | #include <sys/socket.h>
|
87 | #include <arpa/inet.h>
|
88 |
|
89 | #if defined(__APPLE__)
|
90 | #include <mach/mach_time.h>
|
91 |
|
92 | static uint64 GetMicroseconds()
|
93 | {
|
94 |
|
95 |
|
96 | static mach_timebase_info_data_t sTimebaseInfo;
|
97 | static uint64_t start_tick = 0;
|
98 | uint64_t tick;
|
99 |
|
100 | tick = mach_absolute_time();
|
101 | if (sTimebaseInfo.denom == 0) {
|
102 |
|
103 | mach_timebase_info(&sTimebaseInfo);
|
104 | start_tick = tick;
|
105 | }
|
106 |
|
107 | return ((tick - start_tick) * sTimebaseInfo.numer) / (sTimebaseInfo.denom * 1000);
|
108 | }
|
109 |
|
110 | #else //!__APPLE__
|
111 |
|
112 |
|
113 |
|
114 |
|
115 |
|
116 | static uint64_t GetMicroseconds()
|
117 | {
|
118 | static int have_posix_clocks = -1;
|
119 | int rc;
|
120 |
|
121 | #if defined(_POSIX_TIMERS200809L) && _POSIX_TIMERS200809L > 0 && defined(CLOCK_MONOTONIC1)
|
122 | if (have_posix_clocks < 0) {
|
123 | struct timespec ts;
|
124 | rc = clock_gettime(CLOCK_MONOTONIC1, &ts);
|
125 | if (rc < 0) {
|
126 | have_posix_clocks = 0;
|
127 | } else {
|
128 | have_posix_clocks = 1;
|
129 | }
|
130 | }
|
131 |
|
132 | if (have_posix_clocks) {
|
133 | struct timespec ts;
|
134 | rc = clock_gettime(CLOCK_MONOTONIC1, &ts);
|
135 | return uint64(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000;
|
136 | }
|
137 | #endif
|
138 | {
|
139 | struct timeval tv;
|
140 | rc = gettimeofday(&tv, NULL__null);
|
| Value stored to 'rc' is never read |
141 | return uint64(tv.tv_sec) * 1000000 + tv.tv_usec;
|
142 | }
|
143 | }
|
144 | #endif //!__APPLE__
|
145 |
|
146 | #endif //!WIN32
|
147 |
|
148 | uint64 UTP_GetMicroseconds()
|
149 | {
|
150 | static uint64 offset = 0, previous = 0;
|
151 |
|
152 | uint64 now = GetMicroseconds() + offset;
|
153 | if (previous > now) {
|
154 |
|
155 | offset += previous - now;
|
156 | now = previous;
|
157 | }
|
158 | previous = now;
|
159 | return now;
|
160 | }
|
161 |
|
162 | uint32 UTP_GetMilliseconds()
|
163 | {
|
164 | return UTP_GetMicroseconds() / 1000;
|
165 | }
|
166 |
|
167 |
|
168 | #define ETHERNET_MTU1500 1500
|
169 | #define IPV4_HEADER_SIZE20 20
|
170 | #define IPV6_HEADER_SIZE40 40
|
171 | #define UDP_HEADER_SIZE8 8
|
172 | #define GRE_HEADER_SIZE24 24
|
173 | #define PPPOE_HEADER_SIZE8 8
|
174 | #define MPPE_HEADER_SIZE2 2
|
175 |
|
176 |
|
177 |
|
178 | #define FUDGE_HEADER_SIZE36 36
|
179 | #define TEREDO_MTU1280 1280
|
180 |
|
181 | #define UDP_IPV4_OVERHEAD(20 + 8) (IPV4_HEADER_SIZE20 + UDP_HEADER_SIZE8)
|
182 | #define UDP_IPV6_OVERHEAD(40 + 8) (IPV6_HEADER_SIZE40 + UDP_HEADER_SIZE8)
|
183 | #define UDP_TEREDO_OVERHEAD((20 + 8) + (40 + 8)) (UDP_IPV4_OVERHEAD(20 + 8) + UDP_IPV6_OVERHEAD(40 + 8))
|
184 |
|
185 | #define UDP_IPV4_MTU(1500 - 20 - 8 - 24 - 8 - 2 - 36) (ETHERNET_MTU1500 - IPV4_HEADER_SIZE20 - UDP_HEADER_SIZE8 - GRE_HEADER_SIZE24 - PPPOE_HEADER_SIZE8 - MPPE_HEADER_SIZE2 - FUDGE_HEADER_SIZE36)
|
186 | #define UDP_IPV6_MTU(1500 - 40 - 8 - 24 - 8 - 2 - 36) (ETHERNET_MTU1500 - IPV6_HEADER_SIZE40 - UDP_HEADER_SIZE8 - GRE_HEADER_SIZE24 - PPPOE_HEADER_SIZE8 - MPPE_HEADER_SIZE2 - FUDGE_HEADER_SIZE36)
|
187 | #define UDP_TEREDO_MTU(1280 - 8) (TEREDO_MTU1280 - UDP_HEADER_SIZE8)
|
188 |
|
189 | uint16 UTP_GetUDPMTU(const struct sockaddr *remote, socklen_t remotelen)
|
190 | {
|
191 |
|
192 |
|
193 | return remote->sa_family == AF_INET610 ? UDP_TEREDO_MTU(1280 - 8) : UDP_IPV4_MTU(1500 - 20 - 8 - 24 - 8 - 2 - 36);
|
194 | }
|
195 |
|
196 | uint16 UTP_GetUDPOverhead(const struct sockaddr *remote, socklen_t remotelen)
|
197 | {
|
198 |
|
199 |
|
200 | return remote->sa_family == AF_INET610 ? UDP_TEREDO_OVERHEAD((20 + 8) + (40 + 8)) : UDP_IPV4_OVERHEAD(20 + 8);
|
201 | }
|
202 |
|
203 | uint32 UTP_Random()
|
204 | {
|
205 | return rand();
|
206 | }
|
207 |
|
208 | void UTP_DelaySample(const struct sockaddr *remote, int sample_ms) {}
|
209 | size_t UTP_GetPacketSize(const struct sockaddr *remote) { return 1500; }
|
210 |
|