test_socks.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MPL-2.0 */
2 
3 #ifdef _WIN32
4 #include "../src/windows.hpp"
5 #else
6 #include <sys/socket.h>
7 #include <netinet/in.h>
8 #include <arpa/inet.h>
9 #include <unistd.h>
10 #endif
11 
12 #include <stdlib.h>
13 #include <string.h>
14 #include <stdio.h>
15 #include <fcntl.h>
16 #include <errno.h>
17 
18 #include "testutil.hpp"
19 #include "testutil_unity.hpp"
20 
21 
23 
24 void recvall (int sock_fd, char *buffer, int len)
25 {
26  int res;
27  int total = 0;
28  while (len - total > 0) {
29  res = recv (sock_fd, buffer + total, len - total, 0);
30  if (res == -1)
31  fprintf (stderr, "socks_server: error receiving %d bytes: %d %d\n",
32  len, res, errno);
34  TEST_ASSERT (res != 0);
35  total += res;
36  }
37  TEST_ASSERT (total == len);
38 }
39 
40 int recvonce (int sock_fd, char *buffer, int len)
41 {
42  int res;
43  res = recv (sock_fd, buffer, len, 0);
44  if (res == -1)
45  fprintf (stderr, "socks_server: error receiving bytes: %d %d\n", res,
46  errno);
48  return res;
49 }
50 
51 void sendall (int sock_fd, char *buffer, int len)
52 {
53  int res;
54  int total = 0;
55  while (len - total > 0) {
56  res = send (sock_fd, buffer + total, len - total, 0);
57  if (res == -1)
58  fprintf (stderr, "socks_server: error sending %d bytes: %d %d\n",
59  len, res, errno);
61  TEST_ASSERT (res != 0);
62  total += res;
63  }
64 }
65 
66 int remote_connect (int socket, uint32_t addr, uint16_t port)
67 {
68  int res;
69  struct sockaddr_in ip4addr;
70  ip4addr.sin_family = AF_INET;
71  ip4addr.sin_addr.s_addr = htonl (addr);
72  ip4addr.sin_port = htons (port);
73  res = connect (socket, (struct sockaddr *) &ip4addr, sizeof ip4addr);
74  return res;
75 }
76 
77 void *setup_socks_server (char *socks_server_address,
78  int socks_server_address_len)
79 {
80  LIBZMQ_UNUSED (socks_server_address_len);
81  fprintf (stderr, "socks_server: setup socks server\n");
82  int server_fd =
83  bind_socket_resolve_port ("127.0.0.1", "0", socks_server_address);
84  memmove (socks_server_address, strchr (socks_server_address, '/') + 2,
85  strlen (strchr (socks_server_address, '/') + 1));
86  fprintf (stderr, "socks_server: bound to: tcp://%s\n",
87  socks_server_address);
88  return (void *) (intptr_t) server_fd;
89 }
90 
91 void socks_server_task (void *socks_server,
92  const char *username,
93  const char *password,
94  int max_client_connect)
95 {
96  int server_fd = (int) (intptr_t) socks_server;
97  fprintf (stderr, "socks_server: starting server thread\n");
98 
99  int res;
100  res = listen (server_fd, max_client_connect);
102 
103  int auth_method;
104  if (username == NULL || username[0] == '\0') {
105  auth_method = 0x0; /* No auth */
106  } else {
107  auth_method = 0x2; /* Basic auth */
108  if (password == NULL)
109  password = "";
110  }
111 
112  int count = 0;
113  while (count < max_client_connect) {
114  int client = -1;
115  do {
116  char buffer[4096];
117  fprintf (stderr, "socks_server: waiting for connection\n");
118  client = accept (server_fd, NULL, NULL);
120  count++;
121  fprintf (stderr, "socks_server: accepted client connection %d/%d\n",
122  count, max_client_connect);
123 
124  /* Greetings [version, nmethods, methods...]. */
125  recvall (client, buffer, 2);
126  TEST_ASSERT (buffer[0] == 0x5);
127  int nmethods = buffer[1];
128  int method = 0xff;
129  recvall (client, buffer, nmethods);
130  for (int i = 0; i < nmethods; i++) {
131  if (buffer[i] == auth_method)
132  method = auth_method;
133  }
134  fprintf (stderr, "socks_server: received greetings\n");
135 
136  /* Greetings response [version, method]. */
137  buffer[0] = 0x5;
138  buffer[1] = method;
139  sendall (client, buffer, 2);
140  fprintf (stderr,
141  "socks_server: answered greetings (method: 0x%x)\n",
142  method);
143 
144  if (method == 0xff)
145  break; /* Out of client connection */
146 
147  if (method == 0x2) {
148  int len;
149  int err = 0;
150  recvall (client, buffer, 1);
151  if (buffer[0] != 0x1) {
152  err = 1;
153  } else {
154  recvall (client, buffer, 1);
155  len = (unsigned char) buffer[0];
156  recvall (client, buffer, len);
157  buffer[len] = '\0';
158  if (strcmp (username, buffer) != 0) {
159  fprintf (stderr,
160  "socks_server: error on username check: '%s', "
161  "expected: '%s'\n",
162  buffer, username);
163  err = 1;
164  }
165  recvall (client, buffer, 1);
166  len = (unsigned char) buffer[0];
167  recvall (client, buffer, len);
168  buffer[len] = '\0';
169  if (strcmp (password, buffer) != 0) {
170  fprintf (stderr,
171  "socks_server: error on password check: '%s', "
172  "expected: '%s'\n",
173  buffer, password);
174  err = 1;
175  }
176  }
177  fprintf (stderr, "socks_server: received credentials\n");
178  buffer[0] = 0x1;
179  buffer[1] = err;
180  sendall (client, buffer, 2);
181  fprintf (stderr,
182  "socks_server: answered credentials (err: 0x%x)\n",
183  err);
184  if (err != 0)
185  break; /* Out of client connection. */
186  }
187 
188  /* Request [version, cmd, rsv, atype, dst.addr, dst.port */
189  /* Test only tcp connect on top of IPV4 */
190  recvall (client, buffer, 4);
191  TEST_ASSERT (buffer[0] == 0x5);
192  TEST_ASSERT (buffer[1] == 0x1); /* CONNECT cmd */
193  TEST_ASSERT (buffer[2] == 0x0); /* reserved, ensure we send 0 */
194  fprintf (stderr,
195  "socks_server: received command (cmd: %d, atype: %d)\n",
196  buffer[1], buffer[3]);
197  /* IPv4 ADDR & PORT */
198  uint32_t naddr = 0, bind_naddr = 0;
199  uint16_t nport = 0, bind_nport = 0;
200  int remote = -1;
201  int err = 0;
202  int request_atype = buffer[3];
203  if (request_atype == 0x1) /* ATYPE IPv4 */ {
204  recvall (client, (char *) &naddr, 4);
205  fprintf (stderr,
206  "socks_server: received address (addr: 0x%x)\n",
207  ntohl (naddr));
208  } else if (request_atype == 0x3) /* ATYPE DOMAINNAME */ {
209  int len;
210  recvall (client, buffer, 1);
211  len = (unsigned char) buffer[0];
212  recvall (client, buffer, len);
213  buffer[len] = '\0';
214  fprintf (stderr,
215  "socks_server: received domainname (hostname: %s)\n",
216  buffer);
217  /* For the test we support static resolution of
218  hostname "somedomainnmame.org" to localhost */
219  if (strcmp ("somedomainname.org", buffer) == 0) {
220  naddr = htonl (0x7f000001); /* 127.0.0.1 */
221  } else {
222  err = 0x4; /* Host unreachable */
223  }
224  } else if (request_atype == 0x4) {
225  /* For the test we simulate IPV6 connection request ::1, but connect to IPv4 localhost */
226  unsigned char nipv6local[16] = {0};
227  nipv6local[15] = 1;
228  recvall (client, buffer, 16);
229  fprintf (stderr,
230  "socks_server: received ipv6 address (buffer:");
231  for (int i = 0; i < 16; i++)
232  fprintf (stderr, " 0x%x", (unsigned char) buffer[i]);
233  fprintf (stderr, ")\n");
234  if (memcmp (buffer, nipv6local, 16) == 0) {
235  naddr = htonl (0x7f000001); /* 127.0.0.1 */
236  } else {
237  err = 0x4; /* Host unreachable */
238  }
239  } else {
240  err = 0x8; /* ATYPE not supported */
241  }
242  recvall (client, (char *) &nport, 2);
243  fprintf (stderr, "socks_server: received port (port: %d)\n",
244  ntohs (nport));
245  if (err == 0) {
246  fprintf (stderr, "socks_server: trying to connect to %x:%d\n",
247  ntohl (naddr), ntohs (nport));
248  remote = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
249  res = remote_connect (remote, ntohl (naddr), ntohs (nport));
250  if (res != 0) {
251  err = 0x5; /* Connection refused */
252  } else {
253  struct sockaddr_in ip4addr;
254  socklen_t len = sizeof (ip4addr);
255  res =
256  getsockname (remote, (struct sockaddr *) &ip4addr, &len);
258  fprintf (stderr,
259  "socks_server: connected and bound at: %x:%d\n",
260  ntohl (ip4addr.sin_addr.s_addr),
261  ntohs (ip4addr.sin_port));
262  bind_naddr = ip4addr.sin_addr.s_addr;
263  bind_nport = ip4addr.sin_port;
264  }
265  }
266 
267  /* Reply request */
268  buffer[0] = 0x5;
269  buffer[1] = err;
270  buffer[2] = 0;
271  buffer[3] = request_atype;
272  sendall (client, buffer, 4);
273  if (request_atype == 0x1) /* ATYPE IPv4 */ {
274  sendall (client, (char *) &bind_naddr, 4);
275  } else if (request_atype == 0x3) {
276  /* This is just for testing reply with a hostname,
277  normally a resolved address is passed in return to connect. */
278  buffer[0] = strlen ("localhost");
279  sendall (client, buffer, 1);
280  strcpy (buffer, "localhost");
281  sendall (client, buffer, strlen ("localhost"));
282  } else if (request_atype == 0x4) {
283  /* We simulate a bind to ::1, though the actual connection is IPv4 */
284  char nipv6local[16] = {0};
285  nipv6local[15] = 1;
286  sendall (client, nipv6local, sizeof nipv6local);
287  }
288  sendall (client, (char *) &bind_nport, 2);
289  fprintf (stderr, "socks_server: replied to request (err: 0x%x)\n",
290  err);
291  if (err != 0)
292  break; /* Out of client connection. */
293 
294  /* Communication loop */
295  zmq_pollitem_t items[] = {
296  {NULL, client, ZMQ_POLLIN, 0},
297  {NULL, remote, ZMQ_POLLIN, 0},
298  };
299  fprintf (stderr,
300  "socks_server: waiting for input (client fd: %d, remote "
301  "fd: %d)\n",
302  client, remote);
303  while (1) {
304  if (client == -1 || remote == -1)
305  break;
306  if (zmq_poll (items, 2, -1) < 0)
307  break;
308  int nbytes;
309  for (int i = 0; i < 2; i++) {
310  if ((items[i].revents & ZMQ_POLLIN) == 0)
311  continue;
312  fprintf (stderr, "socks_server: ready to read from fd %d\n",
313  items[i].fd);
314  int write_fd, read_fd = items[i].fd;
315  if (read_fd == client) {
316  write_fd = remote;
317  } else {
318  write_fd = client;
319  }
320  nbytes = recvonce (read_fd, buffer, sizeof buffer);
321  fprintf (stderr, "socks_server: read returned: %d\n",
322  nbytes);
323  if (nbytes == 0 || nbytes == -1) {
324  /* End of stream or error */
325  if (read_fd == client) {
326  close (client);
327  client = -1;
328  }
329  if (read_fd == remote) {
330  close (remote);
331  remote = -1;
332  }
333  break;
334  }
335  sendall (write_fd, buffer, nbytes);
336  }
337  }
338  if (remote != -1) {
339  close (remote);
340  remote = -1;
341  }
342  fprintf (stderr, "socks_server: closed remote connection %d/%d\n",
343  count, max_client_connect);
344  } while (0); /* Client socket scope. */
345  if (client != -1) {
346  close (client);
347  client = -1;
348  }
349  fprintf (stderr, "socks_server: closed client connection %d/%d\n",
350  count, max_client_connect);
351  }
352  close (server_fd);
353  fprintf (stderr, "socks_server: closed server\n");
354 }
355 
356 void socks_server_no_auth (void *socks_server)
357 {
358  socks_server_task (socks_server, NULL, NULL, 1);
359 }
360 
361 void socks_server_no_auth_delay (void *socks_server)
362 {
363  fprintf (stderr, "socks_server: delay no auth socks server start\n");
364  // Enough delay to have client connecting before proxy listens
365  msleep (SETTLE_TIME * 10);
366  socks_server_task (socks_server, NULL, NULL, 1);
367 }
368 
369 void socks_server_basic_auth (void *socks_server)
370 {
371  socks_server_task (socks_server, "someuser", "somepass", 1);
372 }
373 
374 void socks_server_basic_auth_delay (void *socks_server)
375 {
376  fprintf (stderr, "socks_server: delay basic auth socks server start\n");
377  // Enough delay to have client connecting before proxy listens
378  msleep (SETTLE_TIME * 10);
379  socks_server_task (socks_server, "someuser", "somepass", 1);
380 }
381 
382 void socks_server_basic_auth_no_pass (void *socks_server)
383 {
384  socks_server_task (socks_server, "someuser", NULL, 1);
385 }
386 
387 void *setup_push_server (char *connect_address, int connect_address_size)
388 {
389  int res;
390  const char *bind_address = "tcp://127.0.0.1:*";
392  res = zmq_bind (push, bind_address);
394  size_t len = connect_address_size;
397  fprintf (stderr, "push_server: bound to: %s\n", connect_address);
398  return push;
399 }
400 
401 void *setup_pull_client (const char *connect_address, const char *socks_proxy)
402 {
403  int res;
404  void *pull = test_context_socket (ZMQ_PULL);
405  if (socks_proxy != NULL) {
406  res = zmq_setsockopt (pull, ZMQ_SOCKS_PROXY, socks_proxy,
407  strlen (socks_proxy));
409  fprintf (stderr, "pull_client: use socks proxy: tcp://%s\n",
410  socks_proxy);
411  }
412  res = zmq_connect (pull, connect_address);
414  fprintf (stderr, "pull_client: connected to: %s\n", connect_address);
415  return pull;
416 }
417 
418 #ifdef ZMQ_BUILD_DRAFT_API
419 void *setup_pull_client_with_auth (const char *connect_address,
420  const char *socks_proxy,
421  const char *username,
422  const char *password)
423 {
424  int res;
425  void *pull = test_context_socket (ZMQ_PULL);
426 
427  if (socks_proxy != NULL) {
428  res = zmq_setsockopt (pull, ZMQ_SOCKS_PROXY, socks_proxy,
429  strlen (socks_proxy));
431  fprintf (stderr, "pull_client: use socks proxy: tcp://%s\n",
432  socks_proxy);
433  }
434 
435  res = zmq_setsockopt (pull, ZMQ_SOCKS_USERNAME, username,
436  username == NULL ? 0 : strlen (username));
438 
439  res = zmq_setsockopt (pull, ZMQ_SOCKS_PASSWORD, password,
440  password == NULL ? 0 : strlen (password));
442 
443  res = zmq_connect (pull, connect_address);
445  fprintf (stderr, "pull_client: connected to: %s\n", connect_address);
446  return pull;
447 }
448 #endif
449 
450 void communicate (void *push, void *pull)
451 {
452  fprintf (stderr, "push_server: sending 2 messages\n");
453  s_send_seq (push, "ABC", SEQ_END);
454  s_send_seq (push, "DEF", SEQ_END);
455 
456  fprintf (stderr, "pull_client: receiving 2 messages\n");
457  s_recv_seq (pull, "ABC", SEQ_END);
458  s_recv_seq (pull, "DEF", SEQ_END);
459 }
460 
462 {
464 
466  void *pull = setup_pull_client (connect_address, NULL);
467  communicate (push, pull);
468 
471 }
472 
473 void test_socks (void)
474 {
475  char socks_server_address[MAX_SOCKET_STRING];
477 
478  void *socks =
479  setup_socks_server (socks_server_address, sizeof socks_server_address);
481  void *pull = setup_pull_client (connect_address, socks_server_address);
482  void *thread = zmq_threadstart (&socks_server_no_auth, socks);
483 
484  communicate (push, pull);
485 
488 
489  zmq_threadclose (thread);
490 }
491 
492 void test_socks_delay (void)
493 {
494  char socks_server_address[MAX_SOCKET_STRING];
496 
497  void *socks =
498  setup_socks_server (socks_server_address, sizeof socks_server_address);
500  void *pull = setup_pull_client (connect_address, socks_server_address);
501  void *thread = zmq_threadstart (&socks_server_no_auth_delay, socks);
502 
503  communicate (push, pull);
504 
507 
508  zmq_threadclose (thread);
509 }
510 
512 {
513  char socks_server_address[MAX_SOCKET_STRING];
515  char connect_address_hostname[MAX_SOCKET_STRING];
516 
517  void *socks =
518  setup_socks_server (socks_server_address, sizeof socks_server_address);
520  // Will be resolved by the proxy test server to 127.0.0.1
521  strcpy (connect_address_hostname, "tcp://somedomainname.org");
522  strcat (connect_address_hostname, strrchr (connect_address, ':'));
523  void *pull =
524  setup_pull_client (connect_address_hostname, socks_server_address);
525  void *thread = zmq_threadstart (&socks_server_no_auth, socks);
526 
527  communicate (push, pull);
528 
531 
532  zmq_threadclose (thread);
533 }
534 
535 void test_socks_ipv6 (void)
536 {
537  char socks_server_address[MAX_SOCKET_STRING];
539  char connect_address_hostname[MAX_SOCKET_STRING];
540 
541  void *socks =
542  setup_socks_server (socks_server_address, sizeof socks_server_address);
544  // Will be resolved by the proxy test server to 127.0.0.1
545  strcpy (connect_address_hostname, "tcp://::1");
546  strcat (connect_address_hostname, strrchr (connect_address, ':'));
547  void *pull =
548  setup_pull_client (connect_address_hostname, socks_server_address);
549  void *thread = zmq_threadstart (&socks_server_no_auth, socks);
550 
551  communicate (push, pull);
552 
555 
556  zmq_threadclose (thread);
557 }
558 
560 {
561  char socks_server_address[MAX_SOCKET_STRING];
563  char connect_address_hostname[MAX_SOCKET_STRING];
564 
565  void *socks =
566  setup_socks_server (socks_server_address, sizeof socks_server_address);
568  // Will be resolved by the proxy test server to 127.0.0.1
569  strcpy (connect_address_hostname, "tcp://[::1]");
570  strcat (connect_address_hostname, strrchr (connect_address, ':'));
571  void *pull =
572  setup_pull_client (connect_address_hostname, socks_server_address);
573  void *thread = zmq_threadstart (&socks_server_no_auth, socks);
574 
575  communicate (push, pull);
576 
579 
580  zmq_threadclose (thread);
581 }
582 
584 {
585  char socks_server_address[MAX_SOCKET_STRING];
587  char socks_address_bind_before_connect[MAX_SOCKET_STRING * 2];
588 
589  void *socks =
590  setup_socks_server (socks_server_address, sizeof socks_server_address);
591  // Will do a bind before connect when connecting to proxy
592  strcpy (socks_address_bind_before_connect, "127.0.0.1:0;");
593  strcat (socks_address_bind_before_connect, socks_server_address);
595  void *pull =
596  setup_pull_client (connect_address, socks_address_bind_before_connect);
597  void *thread = zmq_threadstart (&socks_server_no_auth, socks);
598 
599  communicate (push, pull);
600 
603 
604  zmq_threadclose (thread);
605 }
606 
608 {
609 #ifdef ZMQ_BUILD_DRAFT_API
610  char socks_server_address[MAX_SOCKET_STRING];
612 
613  void *socks =
614  setup_socks_server (socks_server_address, sizeof socks_server_address);
616  void *pull = setup_pull_client_with_auth (
617  connect_address, socks_server_address, "someuser", "somepass");
618  void *thread = zmq_threadstart (&socks_server_basic_auth, socks);
619 
620  communicate (push, pull);
621 
624 
625  zmq_threadclose (thread);
626 #else
628  "libzmq without DRAFT support, ignoring socks basic auth test");
629 #endif
630 }
631 
633 {
634 #ifdef ZMQ_BUILD_DRAFT_API
635  char socks_server_address[MAX_SOCKET_STRING];
637 
638  void *socks =
639  setup_socks_server (socks_server_address, sizeof socks_server_address);
641  void *pull = setup_pull_client_with_auth (
642  connect_address, socks_server_address, "someuser", "somepass");
643  void *thread = zmq_threadstart (&socks_server_basic_auth_delay, socks);
644 
645  communicate (push, pull);
646 
649 
650  zmq_threadclose (thread);
651 #else
653  "libzmq without DRAFT support, ignoring socks basic auth test");
654 #endif
655 }
656 
658 {
659 #ifdef ZMQ_BUILD_DRAFT_API
660  char socks_server_address[MAX_SOCKET_STRING];
662 
663  void *socks =
664  setup_socks_server (socks_server_address, sizeof socks_server_address);
666  void *pull = setup_pull_client_with_auth (connect_address,
667  socks_server_address, "", NULL);
668  void *thread = zmq_threadstart (&socks_server_no_auth, socks);
669 
670  communicate (push, pull);
671 
674 
675  zmq_threadclose (thread);
676 #else
678  "libzmq without DRAFT support, ignoring socks basic auth test");
679 #endif
680 }
681 
683 {
684 #ifdef ZMQ_BUILD_DRAFT_API
685  char socks_server_address[MAX_SOCKET_STRING];
687 
688  void *socks =
689  setup_socks_server (socks_server_address, sizeof socks_server_address);
691  void *pull = setup_pull_client_with_auth (connect_address,
692  socks_server_address, NULL, NULL);
693  void *thread = zmq_threadstart (&socks_server_no_auth, socks);
694 
695  communicate (push, pull);
696 
699 
700  zmq_threadclose (thread);
701 #else
703  "libzmq without DRAFT support, ignoring socks basic auth test");
704 #endif
705 }
706 
708 {
709 #ifdef ZMQ_BUILD_DRAFT_API
710  char socks_server_address[MAX_SOCKET_STRING];
712 
713  void *socks =
714  setup_socks_server (socks_server_address, sizeof socks_server_address);
716  void *pull = setup_pull_client_with_auth (
717  connect_address, socks_server_address, "someuser", "");
718  void *thread = zmq_threadstart (&socks_server_basic_auth_no_pass, socks);
719 
720  communicate (push, pull);
721 
724 
725  zmq_threadclose (thread);
726 #else
728  "libzmq without DRAFT support, ignoring socks basic auth test");
729 #endif
730 }
731 
733 {
734 #ifdef ZMQ_BUILD_DRAFT_API
735  char socks_server_address[MAX_SOCKET_STRING];
737 
738  void *socks =
739  setup_socks_server (socks_server_address, sizeof socks_server_address);
741  void *pull = setup_pull_client_with_auth (
742  connect_address, socks_server_address, "someuser", NULL);
743  void *thread = zmq_threadstart (&socks_server_basic_auth_no_pass, socks);
744 
745  communicate (push, pull);
746 
749 
750  zmq_threadclose (thread);
751 #else
753  "libzmq without DRAFT support, ignoring socks basic auth test");
754 #endif
755 }
756 
757 
758 void test_string_opt_ok (const char *msg, int opt, const char *value)
759 {
760  int res;
761  void *sub = test_context_socket (ZMQ_SUB);
762  fprintf (stderr, "test_string_opt_ok: testing %s\n", msg);
763  res = zmq_setsockopt (sub, opt, value, strlen (value));
765  char buffer[1024];
766  size_t res_len = (size_t) sizeof buffer;
767  res = zmq_getsockopt (sub, opt, buffer, &res_len);
769  TEST_ASSERT_EQUAL (strlen (value) + 1, res_len);
770  TEST_ASSERT (strcmp (buffer, value) == 0);
772 }
773 
774 void test_opt_ok (const char *msg,
775  int opt,
776  const char *value,
777  size_t len,
778  const char *expected_value,
779  size_t expected_len)
780 {
781  int res;
782  void *sub = test_context_socket (ZMQ_SUB);
783  fprintf (stderr, "test_opt_ok: testing %s\n", msg);
784  res = zmq_setsockopt (sub, opt, value, len);
786  char buffer[1024];
787  size_t res_len = (size_t) sizeof buffer;
788  res = zmq_getsockopt (sub, opt, buffer, &res_len);
790  TEST_ASSERT_EQUAL (expected_len + 1, res_len);
791  TEST_ASSERT_EQUAL (expected_len, strlen (buffer));
792  TEST_ASSERT (strncmp (buffer, expected_value, expected_len) == 0);
794 }
795 
796 void test_opt_invalid (const char *msg, int opt, const char *value, int len)
797 {
798  int res;
799  void *sub = test_context_socket (ZMQ_SUB);
800  fprintf (stderr, "test_opt_invalid: testing %s\n", msg);
801  res = zmq_setsockopt (sub, opt, value, len);
804 }
805 
807 {
808  // NULL is equivalent to not set and returns empty string
809  test_opt_ok ("NULL proxy", ZMQ_SOCKS_PROXY, NULL, 0, "", 0);
810  test_string_opt_ok ("valid proxy", ZMQ_SOCKS_PROXY, "somehost:1080");
811  // Empty value not allowed for proxy server
812  test_opt_invalid ("empty proxy", ZMQ_SOCKS_PROXY, "", 0);
813 }
814 
816 {
817 #ifdef ZMQ_BUILD_DRAFT_API
818  char buffer[1024];
819  for (int i = 0; i < (int) sizeof buffer; i++) {
820  buffer[i] = 'a' + i % 26;
821  }
822 
823  // NULL is equivalent to not-set or ""
824  test_opt_ok ("NULL username", ZMQ_SOCKS_USERNAME, NULL, 0, "", 0);
825  // Empty value is allowed for username, means no authentication
826  test_string_opt_ok ("empty username", ZMQ_SOCKS_USERNAME, "");
827  test_string_opt_ok ("valid username", ZMQ_SOCKS_USERNAME, "someuser");
828  test_opt_ok ("255 bytes username", ZMQ_SOCKS_USERNAME, buffer, 255, buffer,
829  255);
830  test_opt_invalid ("too long username", ZMQ_SOCKS_USERNAME, buffer, 256);
831 
832  // NULL is equivalent to not-set or ""
833  test_opt_ok ("NULL password", ZMQ_SOCKS_PASSWORD, NULL, 0, "", 0);
834  // Empty value allowed for password
835  test_string_opt_ok ("empty password", ZMQ_SOCKS_PASSWORD, "");
836  test_string_opt_ok ("valid password", ZMQ_SOCKS_PASSWORD, "someuser");
837  test_opt_ok ("255 bytes password", ZMQ_SOCKS_PASSWORD, buffer, 255, buffer,
838  255);
839  test_opt_invalid ("too long password", ZMQ_SOCKS_PASSWORD, buffer, 256);
840 #else
841  TEST_IGNORE_MESSAGE ("libzmq without DRAFT support, ignoring socks setopt "
842  "username/password test");
843 #endif
844 }
845 
846 int main ()
847 {
849 
850  UNITY_BEGIN ();
866  return UNITY_END ();
867 }
ZMQ_SOCKS_PASSWORD
#define ZMQ_SOCKS_PASSWORD
Definition: zmq_draft.h:32
socks_server_no_auth_delay
void socks_server_no_auth_delay(void *socks_server)
Definition: test_socks.cpp:361
bind_address
const SETUP_TEARDOWN_TESTCONTEXT char bind_address[]
Definition: test_xpub_topic.cpp:8
zmq_pollitem_t::fd
zmq_fd_t fd
Definition: zmq.h:490
NULL
NULL
Definition: test_security_zap.cpp:405
test_socks_basic_auth
void test_socks_basic_auth(void)
Definition: test_socks.cpp:607
UNITY_END
return UNITY_END()
zmq_threadstart
ZMQ_EXPORT void * zmq_threadstart(zmq_thread_fn *func_, void *arg_)
Definition: zmq_utils.cpp:54
sendall
void sendall(int sock_fd, char *buffer, int len)
Definition: test_socks.cpp:51
EINVAL
#define EINVAL
Definition: errno.hpp:25
test_socks_basic_auth_null_pass
void test_socks_basic_auth_null_pass(void)
Definition: test_socks.cpp:732
msleep
void msleep(int milliseconds_)
Definition: testutil.cpp:227
socks_server_basic_auth
void socks_server_basic_auth(void *socks_server)
Definition: test_socks.cpp:369
zmq_poll
ZMQ_EXPORT int zmq_poll(zmq_pollitem_t *items_, int nitems_, long timeout_)
Definition: zmq.cpp:827
RUN_TEST
#define RUN_TEST(func)
Definition: unity_internals.h:615
test_opt_invalid
void test_opt_invalid(const char *msg, int opt, const char *value, int len)
Definition: test_socks.cpp:796
test_socks_no_socks
void test_socks_no_socks(void)
Definition: test_socks.cpp:461
ZMQ_LAST_ENDPOINT
#define ZMQ_LAST_ENDPOINT
Definition: zmq.h:298
test_socks_proxy_options
void test_socks_proxy_options(void)
Definition: test_socks.cpp:806
SETUP_TEARDOWN_TESTCONTEXT
#define SETUP_TEARDOWN_TESTCONTEXT
Definition: testutil_unity.hpp:172
socks_server_basic_auth_no_pass
void socks_server_basic_auth_no_pass(void *socks_server)
Definition: test_socks.cpp:382
errno
int errno
zmq_pollitem_t
Definition: zmq.h:487
client
void client(int num)
Definition: test_multithread.cpp:134
ZMQ_SUB
#define ZMQ_SUB
Definition: zmq.h:260
send
void send(fd_t fd_, const char(&data_)[N])
Definition: test_security_curve.cpp:209
test_socks_basic_auth_null_user
void test_socks_basic_auth_null_user(void)
Definition: test_socks.cpp:682
test_context_socket_close_zero_linger
void * test_context_socket_close_zero_linger(void *socket_)
Definition: testutil_unity.cpp:215
TEST_ASSERT
#define TEST_ASSERT(condition)
Definition: unity.h:120
zmq_connect
ZMQ_EXPORT int zmq_connect(void *s_, const char *addr_)
Definition: zmq.cpp:307
test_socks_basic_auth_empty_pass
void test_socks_basic_auth_empty_pass(void)
Definition: test_socks.cpp:707
test_socks_ipv6
void test_socks_ipv6(void)
Definition: test_socks.cpp:535
ZMQ_POLLIN
#define ZMQ_POLLIN
Definition: zmq.h:482
recvall
SETUP_TEARDOWN_TESTCONTEXT void recvall(int sock_fd, char *buffer, int len)
Definition: test_socks.cpp:24
remote_connect
int remote_connect(int socket, uint32_t addr, uint16_t port)
Definition: test_socks.cpp:66
test_socks
void test_socks(void)
Definition: test_socks.cpp:473
testutil_unity.hpp
zmq_setsockopt
ZMQ_EXPORT int zmq_setsockopt(void *s_, int option_, const void *optval_, size_t optvallen_)
Definition: zmq.cpp:250
zmq_threadclose
ZMQ_EXPORT void zmq_threadclose(void *thread_)
Definition: zmq_utils.cpp:62
LIBZMQ_UNUSED
#define LIBZMQ_UNUSED(object)
Definition: macros.hpp:6
ZMQ_PUSH
#define ZMQ_PUSH
Definition: zmq.h:266
TEST_ASSERT_SUCCESS_RAW_ERRNO
#define TEST_ASSERT_SUCCESS_RAW_ERRNO(expr)
Definition: testutil_unity.hpp:69
testutil.hpp
setup_pull_client
void * setup_pull_client(const char *connect_address, const char *socks_proxy)
Definition: test_socks.cpp:401
socks_server_task
void socks_server_task(void *socks_server, const char *username, const char *password, int max_client_connect)
Definition: test_socks.cpp:91
setup_socks_server
void * setup_socks_server(char *socks_server_address, int socks_server_address_len)
Definition: test_socks.cpp:77
test_socks_basic_auth_empty_user
void test_socks_basic_auth_empty_user(void)
Definition: test_socks.cpp:657
MAX_SOCKET_STRING
#define MAX_SOCKET_STRING
Definition: libzmq/tests/testutil.hpp:35
err
static UPB_NORETURN void err(tarjan *t)
Definition: ruby/ext/google/protobuf_c/upb.c:5856
zmq_bind
ZMQ_EXPORT int zmq_bind(void *s_, const char *addr_)
Definition: zmq.cpp:299
test_socks_delay
void test_socks_delay(void)
Definition: test_socks.cpp:492
test_socks_userpass_options
void test_socks_userpass_options(void)
Definition: test_socks.cpp:815
test_string_opt_ok
void test_string_opt_ok(const char *msg, int opt, const char *value)
Definition: test_socks.cpp:758
buffer
Definition: buffer_processor.h:43
test_context_socket
void * test_context_socket(int type_)
Definition: testutil_unity.cpp:200
SETTLE_TIME
#define SETTLE_TIME
Definition: libzmq/tests/testutil.hpp:31
TEST_ASSERT_EQUAL
#define TEST_ASSERT_EQUAL(expected, actual)
Definition: unity.h:133
ZMQ_SOCKS_PROXY
#define ZMQ_SOCKS_PROXY
Definition: zmq.h:329
i
int i
Definition: gmock-matchers_test.cc:764
TEST_IGNORE_MESSAGE
#define TEST_IGNORE_MESSAGE(message)
Definition: unity.h:103
main
int main()
Definition: test_socks.cpp:846
SEQ_END
const char * SEQ_END
Definition: testutil.cpp:47
len
int len
Definition: php/ext/google/protobuf/map.c:206
s_send_seq
void s_send_seq(void *socket_,...)
Definition: testutil.cpp:135
test_opt_ok
void test_opt_ok(const char *msg, int opt, const char *value, size_t len, const char *expected_value, size_t expected_len)
Definition: test_socks.cpp:774
setup_test_environment
void setup_test_environment(int timeout_seconds_)
Definition: testutil.cpp:201
UNITY_BEGIN
UNITY_BEGIN()
s_recv_seq
void s_recv_seq(void *socket_,...)
Definition: testutil.cpp:158
connect_address
SETUP_TEARDOWN_TESTCONTEXT char connect_address[MAX_SOCKET_STRING]
Definition: tests/test_fork.cpp:14
test_socks_bind_before_connect
void test_socks_bind_before_connect(void)
Definition: test_socks.cpp:583
push
static void push(tarjan *t, const upb_refcounted *r)
Definition: ruby/ext/google/protobuf_c/upb.c:5890
TEST_ASSERT_FAILURE_ERRNO
#define TEST_ASSERT_FAILURE_ERRNO(error_code, expr)
Definition: testutil_unity.hpp:95
test_socks_basic_auth_delay
void test_socks_basic_auth_delay(void)
Definition: test_socks.cpp:632
socks_server_no_auth
void socks_server_no_auth(void *socks_server)
Definition: test_socks.cpp:356
socks_server_basic_auth_delay
void socks_server_basic_auth_delay(void *socks_server)
Definition: test_socks.cpp:374
communicate
void communicate(void *push, void *pull)
Definition: test_socks.cpp:450
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
recvonce
int recvonce(int sock_fd, char *buffer, int len)
Definition: test_socks.cpp:40
ZMQ_PULL
#define ZMQ_PULL
Definition: zmq.h:265
count
GLint GLsizei count
Definition: glcorearb.h:2830
test_socks_ipv6_sb
void test_socks_ipv6_sb(void)
Definition: test_socks.cpp:559
test_socks_domainname
void test_socks_domainname(void)
Definition: test_socks.cpp:511
setup_push_server
void * setup_push_server(char *connect_address, int connect_address_size)
Definition: test_socks.cpp:387
TEST_ASSERT_SUCCESS_ERRNO
#define TEST_ASSERT_SUCCESS_ERRNO(expr)
Definition: proxy_thr.cpp:47
zmq_getsockopt
ZMQ_EXPORT int zmq_getsockopt(void *s_, int option_, void *optval_, size_t *optvallen_)
Definition: zmq.cpp:261
google::protobuf::method
const Descriptor::ReservedRange const EnumValueDescriptor method
Definition: src/google/protobuf/descriptor.h:1973
bind_socket_resolve_port
fd_t bind_socket_resolve_port(const char *address_, const char *port_, char *my_endpoint_, const int af_, const int protocol_)
Definition: testutil.cpp:410
ZMQ_SOCKS_USERNAME
#define ZMQ_SOCKS_USERNAME
Definition: zmq_draft.h:31


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:59