libuv-svace-build

Форк
0
/
test-udp-open.c 
350 строк · 7.6 Кб
1
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
 *
3
 * Permission is hereby granted, free of charge, to any person obtaining a copy
4
 * of this software and associated documentation files (the "Software"), to
5
 * deal in the Software without restriction, including without limitation the
6
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
 * sell copies of the Software, and to permit persons to whom the Software is
8
 * furnished to do so, subject to the following conditions:
9
 *
10
 * The above copyright notice and this permission notice shall be included in
11
 * all copies or substantial portions of the Software.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19
 * IN THE SOFTWARE.
20
 */
21

22
#include "uv.h"
23
#include "task.h"
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <string.h>
27

28
#ifndef _WIN32
29
# include <unistd.h>
30
# include <sys/socket.h>
31
# include <sys/un.h>
32
#endif
33

34
static int send_cb_called = 0;
35
static int close_cb_called = 0;
36

37
static uv_udp_send_t send_req;
38

39

40
static void startup(void) {
41
#ifdef _WIN32
42
    struct WSAData wsa_data;
43
    int r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
44
    ASSERT_OK(r);
45
#endif
46
}
47

48

49
static uv_os_sock_t create_udp_socket(void) {
50
  uv_os_sock_t sock;
51

52
  sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
53
#ifdef _WIN32
54
  ASSERT_NE(sock, INVALID_SOCKET);
55
#else
56
  ASSERT_GE(sock, 0);
57
#endif
58

59
#ifndef _WIN32
60
  {
61
    /* Allow reuse of the port. */
62
    int yes = 1;
63
    int r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
64
    ASSERT_OK(r);
65
  }
66
#endif
67

68
  return sock;
69
}
70

71

72
static void close_socket(uv_os_sock_t sock) {
73
  int r;
74
#ifdef _WIN32
75
  r = closesocket(sock);
76
#else
77
  r = close(sock);
78
#endif
79
  ASSERT_OK(r);
80
}
81

82

83
static void alloc_cb(uv_handle_t* handle,
84
                     size_t suggested_size,
85
                     uv_buf_t* buf) {
86
  static char slab[65536];
87
  ASSERT_LE(suggested_size, sizeof(slab));
88
  buf->base = slab;
89
  buf->len = sizeof(slab);
90
}
91

92

93
static void close_cb(uv_handle_t* handle) {
94
  ASSERT_NOT_NULL(handle);
95
  close_cb_called++;
96
}
97

98

99
static void recv_cb(uv_udp_t* handle,
100
                       ssize_t nread,
101
                       const uv_buf_t* buf,
102
                       const struct sockaddr* addr,
103
                       unsigned flags) {
104
  int r;
105

106
  if (nread < 0) {
107
    ASSERT(0 && "unexpected error");
108
  }
109

110
  if (nread == 0) {
111
    /* Returning unused buffer. Don't count towards sv_recv_cb_called */
112
    ASSERT_NULL(addr);
113
    return;
114
  }
115

116
  ASSERT_OK(flags);
117

118
  ASSERT_NOT_NULL(addr);
119
  ASSERT_EQ(4, nread);
120
  ASSERT_OK(memcmp("PING", buf->base, nread));
121

122
  r = uv_udp_recv_stop(handle);
123
  ASSERT_OK(r);
124

125
  uv_close((uv_handle_t*) handle, close_cb);
126
}
127

128

129
static void send_cb(uv_udp_send_t* req, int status) {
130
  ASSERT_NOT_NULL(req);
131
  ASSERT_OK(status);
132

133
  send_cb_called++;
134
  uv_close((uv_handle_t*)req->handle, close_cb);
135
}
136

137

138
TEST_IMPL(udp_open) {
139
  struct sockaddr_in addr;
140
  uv_buf_t buf = uv_buf_init("PING", 4);
141
  uv_udp_t client, client2;
142
  uv_os_sock_t sock;
143
  int r;
144

145
  ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
146

147
  startup();
148
  sock = create_udp_socket();
149

150
  r = uv_udp_init(uv_default_loop(), &client);
151
  ASSERT_OK(r);
152

153
  r = uv_udp_open(&client, sock);
154
  ASSERT_OK(r);
155

156
  r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0);
157
  ASSERT_OK(r);
158

159
  r = uv_udp_recv_start(&client, alloc_cb, recv_cb);
160
  ASSERT_OK(r);
161

162
  r = uv_udp_send(&send_req,
163
                  &client,
164
                  &buf,
165
                  1,
166
                  (const struct sockaddr*) &addr,
167
                  send_cb);
168
  ASSERT_OK(r);
169

170
#ifndef _WIN32
171
  {
172
    r = uv_udp_init(uv_default_loop(), &client2);
173
    ASSERT_OK(r);
174

175
    r = uv_udp_open(&client2, sock);
176
    ASSERT_EQ(r, UV_EEXIST);
177

178
    uv_close((uv_handle_t*) &client2, NULL);
179
  }
180
#else  /* _WIN32 */
181
  (void)client2;
182
#endif
183

184
  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
185

186
  ASSERT_EQ(1, send_cb_called);
187
  ASSERT_EQ(1, close_cb_called);
188

189
  ASSERT_OK(client.send_queue_size);
190

191
  MAKE_VALGRIND_HAPPY(uv_default_loop());
192
  return 0;
193
}
194

195

196
TEST_IMPL(udp_open_twice) {
197
  uv_udp_t client;
198
  uv_os_sock_t sock1, sock2;
199
  int r;
200

201
  startup();
202
  sock1 = create_udp_socket();
203
  sock2 = create_udp_socket();
204

205
  r = uv_udp_init(uv_default_loop(), &client);
206
  ASSERT_OK(r);
207

208
  r = uv_udp_open(&client, sock1);
209
  ASSERT_OK(r);
210

211
  r = uv_udp_open(&client, sock2);
212
  ASSERT_EQ(r, UV_EBUSY);
213
  close_socket(sock2);
214

215
  uv_close((uv_handle_t*) &client, NULL);
216
  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
217

218
  MAKE_VALGRIND_HAPPY(uv_default_loop());
219
  return 0;
220
}
221

222
TEST_IMPL(udp_open_bound) {
223
  struct sockaddr_in addr;
224
  uv_udp_t client;
225
  uv_os_sock_t sock;
226
  int r;
227

228
  ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
229

230
  startup();
231
  sock = create_udp_socket();
232

233
  r = bind(sock, (struct sockaddr*) &addr, sizeof(addr));
234
  ASSERT_OK(r);
235

236
  r = uv_udp_init(uv_default_loop(), &client);
237
  ASSERT_OK(r);
238

239
  r = uv_udp_open(&client, sock);
240
  ASSERT_OK(r);
241

242
  r = uv_udp_recv_start(&client, alloc_cb, recv_cb);
243
  ASSERT_OK(r);
244

245
  uv_close((uv_handle_t*) &client, NULL);
246
  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
247

248
  MAKE_VALGRIND_HAPPY(uv_default_loop());
249
  return 0;
250
}
251

252
TEST_IMPL(udp_open_connect) {
253
  struct sockaddr_in addr;
254
  uv_buf_t buf = uv_buf_init("PING", 4);
255
  uv_udp_t client;
256
  uv_udp_t server;
257
  uv_os_sock_t sock;
258
  int r;
259

260
  ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
261

262
  startup();
263
  sock = create_udp_socket();
264

265
  r = uv_udp_init(uv_default_loop(), &client);
266
  ASSERT_OK(r);
267

268
  r = connect(sock, (const struct sockaddr*) &addr, sizeof(addr));
269
  ASSERT_OK(r);
270

271
  r = uv_udp_open(&client, sock);
272
  ASSERT_OK(r);
273

274
  r = uv_udp_init(uv_default_loop(), &server);
275
  ASSERT_OK(r);
276

277
  r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0);
278
  ASSERT_OK(r);
279

280
  r = uv_udp_recv_start(&server, alloc_cb, recv_cb);
281
  ASSERT_OK(r);
282

283
  r = uv_udp_send(&send_req,
284
                  &client,
285
                  &buf,
286
                  1,
287
                  NULL,
288
                  send_cb);
289
  ASSERT_OK(r);
290

291
  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
292

293
  ASSERT_EQ(1, send_cb_called);
294
  ASSERT_EQ(2, close_cb_called);
295

296
  ASSERT_OK(client.send_queue_size);
297

298
  MAKE_VALGRIND_HAPPY(uv_default_loop());
299
  return 0;
300
}
301

302
#ifndef _WIN32
303
TEST_IMPL(udp_send_unix) {
304
  /* Test that "uv_udp_send()" supports sending over
305
     a "sockaddr_un" address. */
306
  struct sockaddr_un addr;
307
  uv_udp_t handle;
308
  uv_udp_send_t req;
309
  uv_loop_t* loop;
310
  uv_buf_t buf = uv_buf_init("PING", 4);
311
  int fd;
312
  int r;
313

314
  loop = uv_default_loop();
315

316
  memset(&addr, 0, sizeof addr);
317
  addr.sun_family = AF_UNIX;
318
  ASSERT_LT(strlen(TEST_PIPENAME), sizeof(addr.sun_path));
319
  memcpy(addr.sun_path, TEST_PIPENAME, strlen(TEST_PIPENAME));
320

321
  fd = socket(AF_UNIX, SOCK_STREAM, 0);
322
  ASSERT_GE(fd, 0);
323

324
  unlink(TEST_PIPENAME);
325
  ASSERT_OK(bind(fd, (const struct sockaddr*)&addr, sizeof addr));
326
  ASSERT_OK(listen(fd, 1));
327

328
  r = uv_udp_init(loop, &handle);
329
  ASSERT_OK(r);
330
  r = uv_udp_open(&handle, fd);
331
  ASSERT_OK(r);
332
  uv_run(loop, UV_RUN_DEFAULT);
333

334
  r = uv_udp_send(&req,
335
                  &handle,
336
                  &buf,
337
                  1,
338
                  (const struct sockaddr*) &addr,
339
                  NULL);
340
  ASSERT_OK(r);
341

342
  uv_close((uv_handle_t*)&handle, NULL);
343
  uv_run(loop, UV_RUN_DEFAULT);
344
  close(fd);
345
  unlink(TEST_PIPENAME);
346

347
  MAKE_VALGRIND_HAPPY(loop);
348
  return 0;
349
}
350
#endif
351

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.