blob: a2e103c93e04903542df3f1a22a0111bf72e2c21 [file] [log] [blame]
Harald Welte4ffb43f2017-01-27 10:29:49 +01001/*
2 * (C) 2017 by Harald Welte <laforge@gnumonks.org>
3 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 */
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <unistd.h>
24#include <string.h>
25#include <fcntl.h>
Pau Espin Pedrolcd133312020-08-19 17:25:04 +020026#include <inttypes.h>
Harald Welte4ffb43f2017-01-27 10:29:49 +010027
28#include <sys/socket.h>
29#include <arpa/inet.h>
30#include <netinet/in.h>
31
Philipp Maier6f0f5602017-02-09 14:09:06 +010032#include <osmocom/core/application.h>
Harald Welte4ffb43f2017-01-27 10:29:49 +010033#include <osmocom/core/utils.h>
34#include <osmocom/core/socket.h>
Philipp Maier6f0f5602017-02-09 14:09:06 +010035#include <osmocom/core/logging.h>
Pau Espin Pedrolcd133312020-08-19 17:25:04 +020036#include <osmocom/core/bits.h>
Harald Welte4ffb43f2017-01-27 10:29:49 +010037
38#include "../config.h"
39
Neels Hofmeyra829b452018-04-05 03:02:35 +020040void *ctx = NULL;
41
Harald Welte4ffb43f2017-01-27 10:29:49 +010042static int test_sockinit(void)
43{
44 int fd, rc;
45 char *name;
46
47 printf("Checking osmo_sock_init() with bind to a random local UDP port\n");
48 fd = osmo_sock_init(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
49 "0.0.0.0", 0, OSMO_SOCK_F_BIND);
50 OSMO_ASSERT(fd >= 0);
Neels Hofmeyra829b452018-04-05 03:02:35 +020051 name = osmo_sock_get_name(ctx, fd);
Harald Welte4ffb43f2017-01-27 10:29:49 +010052 /* expect it to be not connected. We cannot match on INADDR_ANY,
53 * as apparently that won't work on FreeBSD if there's only one
54 * address (e.g. 127.0.0.1) assigned to the entire system, like
55 * the Osmocom FreeBSD build slaves */
Neels Hofmeyr1f82d0a2017-06-21 22:54:46 +020056 OSMO_ASSERT(!strncmp(name, "(r=NULL<->", 9));
Harald Welte4ffb43f2017-01-27 10:29:49 +010057 talloc_free(name);
58 /* expect it to be blocking */
59 rc = fcntl(fd, F_GETFL);
60 OSMO_ASSERT(!(rc & O_NONBLOCK));
61 close(fd);
62
63 printf("Checking for OSMO_SOCK_F_NONBLOCK\n");
64 fd = osmo_sock_init(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
65 "0.0.0.0", 0, OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);
66 OSMO_ASSERT(fd >= 0);
67 /* expect it to be blocking */
68 rc = fcntl(fd, F_GETFL);
69 OSMO_ASSERT(rc & O_NONBLOCK);
70 close(fd);
71
72 printf("Checking for invalid flags\n");
73 fd = osmo_sock_init(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
74 "0.0.0.0", 0, OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT);
75 OSMO_ASSERT(fd < 0);
76
77 return 0;
78}
79
Harald Weltedda70fc2017-04-08 20:52:33 +020080static int test_sockinit2(void)
81{
82 int fd, rc;
83 char *name;
84
85 printf("Checking osmo_sock_init2() with bind to a random local UDP port\n");
86 fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
87 "0.0.0.0", 0, NULL, 0, OSMO_SOCK_F_BIND);
88 OSMO_ASSERT(fd >= 0);
Neels Hofmeyra829b452018-04-05 03:02:35 +020089 name = osmo_sock_get_name(ctx, fd);
Harald Weltedda70fc2017-04-08 20:52:33 +020090 /* expect it to be not connected. We cannot match on INADDR_ANY,
91 * as apparently that won't work on FreeBSD if there's only one
92 * address (e.g. 127.0.0.1) assigned to the entire system, like
93 * the Osmocom FreeBSD build slaves */
Neels Hofmeyr1f82d0a2017-06-21 22:54:46 +020094 OSMO_ASSERT(!strncmp(name, "(r=NULL<->", 9));
Harald Weltedda70fc2017-04-08 20:52:33 +020095 talloc_free(name);
96 /* expect it to be blocking */
97 rc = fcntl(fd, F_GETFL);
98 OSMO_ASSERT(!(rc & O_NONBLOCK));
99 close(fd);
100
101 printf("Checking osmo_sock_init2() for OSMO_SOCK_F_NONBLOCK\n");
102 fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
103 "0.0.0.0", 0, NULL, 0, OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);
104 OSMO_ASSERT(fd >= 0);
105 /* expect it to be blocking */
106 rc = fcntl(fd, F_GETFL);
107 OSMO_ASSERT(rc & O_NONBLOCK);
108 close(fd);
109
110 printf("Checking osmo_sock_init2() for invalid flags\n");
111 fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, "0.0.0.0", 0, NULL, 0, 0);
112 OSMO_ASSERT(fd < 0);
113
114 printf("Checking osmo_sock_init2() for combined BIND + CONNECT\n");
115 fd = osmo_sock_init2(AF_INET, SOCK_DGRAM, IPPROTO_UDP, "127.0.0.1", 0, "127.0.0.1", 53,
116 OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT);
117 OSMO_ASSERT(fd >= 0);
Neels Hofmeyra829b452018-04-05 03:02:35 +0200118 name = osmo_sock_get_name(ctx, fd);
Harald Weltedda70fc2017-04-08 20:52:33 +0200119#ifndef __FreeBSD__
120 /* For some reason, on the jenkins.osmocom.org build slave with
121 * FreeBSD 10 inside a jail, it fails. Works fine on laforge's
122 * FreeBSD 10 or 11 VM at home */
Neels Hofmeyr1f82d0a2017-06-21 22:54:46 +0200123 OSMO_ASSERT(!strncmp(name, "(r=127.0.0.1:53<->l=127.0.0.1", 29));
Harald Weltedda70fc2017-04-08 20:52:33 +0200124#endif
Alexander Couzens2c962f52020-06-03 00:28:02 +0200125
126 printf("Checking osmo_sock_init2(AF_UNSPEC) must fail on mixed IPv4 & IPv6\n");
127 fd = osmo_sock_init2(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "127.0.0.1", 0, "::1", 53,
128 OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT);
129 OSMO_ASSERT(fd < 0);
130
131 printf("Checking osmo_sock_init2(AF_UNSPEC) must fail on mixed IPv6 & IPv4\n");
132 fd = osmo_sock_init2(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "::1", 0, "127.0.0.1", 53,
133 OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT);
134 OSMO_ASSERT(fd < 0);
135
136 printf("Checking osmo_sock_init2(AF_UNSPEC) BIND + CONNECT on IPv4\n");
137 fd = osmo_sock_init2(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "127.0.0.1", 0, "127.0.0.1", 53,
138 OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT);
139 OSMO_ASSERT(fd >= 0);
140
141 printf("Checking osmo_sock_init2(AF_UNSPEC) BIND + CONNECT on IPv6\n");
142 fd = osmo_sock_init2(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "::1", 0, "::1", 53,
143 OSMO_SOCK_F_BIND|OSMO_SOCK_F_CONNECT);
144 OSMO_ASSERT(fd >= 0);
145
Harald Weltedda70fc2017-04-08 20:52:33 +0200146 talloc_free(name);
147
148 return 0;
149}
150
Philipp Maier6f0f5602017-02-09 14:09:06 +0100151const struct log_info_cat default_categories[] = {
152};
153
154static struct log_info info = {
155 .cat = default_categories,
156 .num_cat = ARRAY_SIZE(default_categories),
157};
158
Harald Welte4ffb43f2017-01-27 10:29:49 +0100159int main(int argc, char *argv[])
160{
Neels Hofmeyra829b452018-04-05 03:02:35 +0200161 ctx = talloc_named_const(NULL, 0, "socket_test");
162 osmo_init_logging2(ctx, &info);
Philipp Maier6f0f5602017-02-09 14:09:06 +0100163 log_set_use_color(osmo_stderr_target, 0);
164 log_set_print_filename(osmo_stderr_target, 0);
165
Harald Welte4ffb43f2017-01-27 10:29:49 +0100166 test_sockinit();
Harald Weltedda70fc2017-04-08 20:52:33 +0200167 test_sockinit2();
Philipp Maier6f0f5602017-02-09 14:09:06 +0100168
169 return EXIT_SUCCESS;
Harald Welte4ffb43f2017-01-27 10:29:49 +0100170}