test-getsockname.c
Go to the documentation of this file.
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 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 static const int server_port = TEST_PORT;
30 /* Will be updated right after making the uv_connect_call */
31 static int connect_port = -1;
32 
33 static int getsocknamecount = 0;
34 static int getpeernamecount = 0;
35 
36 static uv_loop_t* loop;
37 static uv_tcp_t tcp;
38 static uv_udp_t udp;
43 
44 
45 static void alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
46  buf->base = malloc(suggested_size);
47  buf->len = suggested_size;
48 }
49 
50 
51 static void on_close(uv_handle_t* peer) {
52  free(peer);
53  uv_close((uv_handle_t*)&tcpServer, NULL);
54 }
55 
56 
57 static void after_shutdown(uv_shutdown_t* req, int status) {
59  free(req);
60 }
61 
62 
64  ssize_t nread,
65  const uv_buf_t* buf) {
67  int r;
68 
69  if (buf->base) {
70  free(buf->base);
71  }
72 
73  req = (uv_shutdown_t*) malloc(sizeof *req);
75  ASSERT(r == 0);
76 }
77 
78 
79 static void check_sockname(struct sockaddr* addr, const char* compare_ip,
80  int compare_port, const char* context) {
81  struct sockaddr_in check_addr = *(struct sockaddr_in*) addr;
82  struct sockaddr_in compare_addr;
83  char check_ip[17];
84  int r;
85 
86  ASSERT(0 == uv_ip4_addr(compare_ip, compare_port, &compare_addr));
87 
88  /* Both addresses should be ipv4 */
89  ASSERT(check_addr.sin_family == AF_INET);
90  ASSERT(compare_addr.sin_family == AF_INET);
91 
92  /* Check if the ip matches */
93  ASSERT(memcmp(&check_addr.sin_addr,
94  &compare_addr.sin_addr,
95  sizeof compare_addr.sin_addr) == 0);
96 
97  /* Check if the port matches. If port == 0 anything goes. */
98  ASSERT(compare_port == 0 || check_addr.sin_port == compare_addr.sin_port);
99 
100  r = uv_ip4_name(&check_addr, (char*) check_ip, sizeof check_ip);
101  ASSERT(r == 0);
102 
103  printf("%s: %s:%d\n", context, check_ip, ntohs(check_addr.sin_port));
104 }
105 
106 
108  struct sockaddr sockname, peername;
109  int namelen;
110  uv_tcp_t* handle;
111  int r;
112 
113  if (status != 0) {
114  fprintf(stderr, "Connect error %s\n", uv_err_name(status));
115  }
116  ASSERT(status == 0);
117 
118  handle = malloc(sizeof(*handle));
119  ASSERT(handle != NULL);
120 
121  r = uv_tcp_init(loop, handle);
122  ASSERT(r == 0);
123 
124  /* associate server with stream */
125  handle->data = server;
126 
128  ASSERT(r == 0);
129 
130  namelen = sizeof sockname;
131  r = uv_tcp_getsockname(handle, &sockname, &namelen);
132  ASSERT(r == 0);
133  check_sockname(&sockname, "127.0.0.1", server_port, "accepted socket");
135 
136  namelen = sizeof peername;
137  r = uv_tcp_getpeername(handle, &peername, &namelen);
138  ASSERT(r == 0);
139  check_sockname(&peername, "127.0.0.1", connect_port, "accepted socket peer");
141 
143  ASSERT(r == 0);
144 }
145 
146 
147 static void on_connect(uv_connect_t* req, int status) {
148  struct sockaddr sockname, peername;
149  int r, namelen;
150 
151  ASSERT(status == 0);
152 
153  namelen = sizeof sockname;
154  r = uv_tcp_getsockname((uv_tcp_t*) req->handle, &sockname, &namelen);
155  ASSERT(r == 0);
156  check_sockname(&sockname, "127.0.0.1", 0, "connected socket");
158 
159  namelen = sizeof peername;
160  r = uv_tcp_getpeername((uv_tcp_t*) req->handle, &peername, &namelen);
161  ASSERT(r == 0);
162  check_sockname(&peername, "127.0.0.1", server_port, "connected socket peer");
164 
165  uv_close((uv_handle_t*)&tcp, NULL);
166 }
167 
168 
169 static int tcp_listener(void) {
170  struct sockaddr_in addr;
171  struct sockaddr sockname, peername;
172  int namelen;
173  int r;
174 
175  ASSERT(0 == uv_ip4_addr("0.0.0.0", server_port, &addr));
176 
178  if (r) {
179  fprintf(stderr, "Socket creation error\n");
180  return 1;
181  }
182 
183  r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr, 0);
184  if (r) {
185  fprintf(stderr, "Bind error\n");
186  return 1;
187  }
188 
190  if (r) {
191  fprintf(stderr, "Listen error\n");
192  return 1;
193  }
194 
195  memset(&sockname, -1, sizeof sockname);
196  namelen = sizeof sockname;
197  r = uv_tcp_getsockname(&tcpServer, &sockname, &namelen);
198  ASSERT(r == 0);
199  check_sockname(&sockname, "0.0.0.0", server_port, "server socket");
201 
202  namelen = sizeof sockname;
203  r = uv_tcp_getpeername(&tcpServer, &peername, &namelen);
204  ASSERT(r == UV_ENOTCONN);
206 
207  return 0;
208 }
209 
210 
211 static void tcp_connector(void) {
212  struct sockaddr_in server_addr;
213  struct sockaddr sockname;
214  int r, namelen;
215 
216  ASSERT(0 == uv_ip4_addr("127.0.0.1", server_port, &server_addr));
217 
218  r = uv_tcp_init(loop, &tcp);
219  tcp.data = &connect_req;
220  ASSERT(!r);
221 
223  &tcp,
224  (const struct sockaddr*) &server_addr,
225  on_connect);
226  ASSERT(!r);
227 
228  /* Fetch the actual port used by the connecting socket. */
229  namelen = sizeof sockname;
230  r = uv_tcp_getsockname(&tcp, &sockname, &namelen);
231  ASSERT(!r);
232  ASSERT(sockname.sa_family == AF_INET);
233  connect_port = ntohs(((struct sockaddr_in*) &sockname)->sin_port);
234  ASSERT(connect_port > 0);
235 }
236 
237 
238 static void udp_recv(uv_udp_t* handle,
239  ssize_t nread,
240  const uv_buf_t* buf,
241  const struct sockaddr* addr,
242  unsigned flags) {
243  struct sockaddr sockname;
244  int namelen;
245  int r;
246 
247  ASSERT(nread >= 0);
248  free(buf->base);
249 
250  if (nread == 0) {
251  return;
252  }
253 
254  memset(&sockname, -1, sizeof sockname);
255  namelen = sizeof(sockname);
256  r = uv_udp_getsockname(&udp, &sockname, &namelen);
257  ASSERT(r == 0);
258  check_sockname(&sockname, "0.0.0.0", 0, "udp receiving socket");
260 
261  uv_close((uv_handle_t*) &udp, NULL);
262  uv_close((uv_handle_t*) handle, NULL);
263 }
264 
265 
266 static void udp_send(uv_udp_send_t* req, int status) {
267 
268 }
269 
270 
271 static int udp_listener(void) {
272  struct sockaddr_in addr;
273  struct sockaddr sockname;
274  int namelen;
275  int r;
276 
277  ASSERT(0 == uv_ip4_addr("0.0.0.0", server_port, &addr));
278 
280  if (r) {
281  fprintf(stderr, "Socket creation error\n");
282  return 1;
283  }
284 
285  r = uv_udp_bind(&udpServer, (const struct sockaddr*) &addr, 0);
286  if (r) {
287  fprintf(stderr, "Bind error\n");
288  return 1;
289  }
290 
291  memset(&sockname, -1, sizeof sockname);
292  namelen = sizeof sockname;
293  r = uv_udp_getsockname(&udpServer, &sockname, &namelen);
294  ASSERT(r == 0);
295  check_sockname(&sockname, "0.0.0.0", server_port, "udp listener socket");
297 
299  ASSERT(r == 0);
300 
301  return 0;
302 }
303 
304 
305 static void udp_sender(void) {
306  struct sockaddr_in server_addr;
307  uv_buf_t buf;
308  int r;
309 
310  r = uv_udp_init(loop, &udp);
311  ASSERT(!r);
312 
313  buf = uv_buf_init("PING", 4);
314  ASSERT(0 == uv_ip4_addr("127.0.0.1", server_port, &server_addr));
315 
317  &udp,
318  &buf,
319  1,
320  (const struct sockaddr*) &server_addr,
321  udp_send);
322  ASSERT(!r);
323 }
324 
325 
326 TEST_IMPL(getsockname_tcp) {
327  loop = uv_default_loop();
328 
329  if (tcp_listener())
330  return 1;
331 
332  tcp_connector();
333 
335 
336  ASSERT(getsocknamecount == 3);
337  ASSERT(getpeernamecount == 3);
338 
340  return 0;
341 }
342 
343 
344 TEST_IMPL(getsockname_udp) {
345  loop = uv_default_loop();
346 
347  if (udp_listener())
348  return 1;
349 
350  udp_sender();
351 
353 
354  ASSERT(getsocknamecount == 2);
355 
356  ASSERT(udp.send_queue_size == 0);
358 
360  return 0;
361 }
after_shutdown
static void after_shutdown(uv_shutdown_t *req, int status)
Definition: test-getsockname.c:57
connect_port
static int connect_port
Definition: test-getsockname.c:31
TEST_IMPL
TEST_IMPL(getsockname_tcp)
Definition: test-getsockname.c:326
task.h
getpeernamecount
static int getpeernamecount
Definition: test-getsockname.c:34
memset
return memset(p, 0, total)
uv_connect_s
Definition: uv.h:580
udpServer
static uv_udp_t udpServer
Definition: test-getsockname.c:41
udp_sender
static void udp_sender(void)
Definition: test-getsockname.c:305
uv_shutdown_s
Definition: uv.h:417
string.h
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
uv_listen
UV_EXTERN int uv_listen(uv_stream_t *stream, int backlog, uv_connection_cb cb)
Definition: unix/stream.c:656
printf
_Use_decl_annotations_ int __cdecl printf(const char *_Format,...)
Definition: cs_driver.c:91
tcp_listener
static int tcp_listener(void)
Definition: test-getsockname.c:169
uv_connect_s::handle
uv_stream_t * handle
Definition: uv.h:583
uv_udp_send
UV_EXTERN int uv_udp_send(uv_udp_send_t *req, uv_udp_t *handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr *addr, uv_udp_send_cb send_cb)
Definition: uv-common.c:408
udp_listener
static int udp_listener(void)
Definition: test-getsockname.c:271
tcpServer
static uv_tcp_t tcpServer
Definition: test-getsockname.c:40
ASSERT
#define ASSERT(expr)
Definition: task.h:102
status
absl::Status status
Definition: rls.cc:251
uv_udp_getsockname
UV_EXTERN int uv_udp_getsockname(const uv_udp_t *handle, struct sockaddr *name, int *namelen)
Definition: unix/udp.c:1293
udp_send
static void udp_send(uv_udp_send_t *req, int status)
Definition: test-getsockname.c:266
uv_run
UV_EXTERN int uv_run(uv_loop_t *, uv_run_mode mode)
Definition: unix/core.c:361
uv_tcp_getsockname
UV_EXTERN int uv_tcp_getsockname(const uv_tcp_t *handle, struct sockaddr *name, int *namelen)
Definition: unix/tcp.c:283
uv_tcp_bind
UV_EXTERN int uv_tcp_bind(uv_tcp_t *handle, const struct sockaddr *addr, unsigned int flags)
Definition: uv-common.c:277
TEST_PORT
#define TEST_PORT
Definition: task.h:53
python_utils.port_server.stderr
stderr
Definition: port_server.py:51
uv_close
UV_EXTERN void uv_close(uv_handle_t *handle, uv_close_cb close_cb)
Definition: unix/core.c:112
uv_stream_s
Definition: uv.h:491
uv_tcp_connect
UV_EXTERN int uv_tcp_connect(uv_connect_t *req, uv_tcp_t *handle, const struct sockaddr *addr, uv_connect_cb cb)
Definition: uv-common.c:315
uv_ip4_addr
UV_EXTERN int uv_ip4_addr(const char *ip, int port, struct sockaddr_in *addr)
Definition: uv-common.c:221
uv_tcp_getpeername
UV_EXTERN int uv_tcp_getpeername(const uv_tcp_t *handle, struct sockaddr *name, int *namelen)
Definition: unix/tcp.c:297
server
std::unique_ptr< Server > server
Definition: channelz_service_test.cc:330
uv_default_loop
UV_EXTERN uv_loop_t * uv_default_loop(void)
Definition: uv-common.c:733
uv_udp_init
UV_EXTERN int uv_udp_init(uv_loop_t *, uv_udp_t *handle)
Definition: unix/udp.c:988
ssize_t
intptr_t ssize_t
Definition: win.h:27
udp_recv
static void udp_recv(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags)
Definition: test-getsockname.c:238
tcp_connector
static void tcp_connector(void)
Definition: test-getsockname.c:211
req
static uv_connect_t req
Definition: test-connection-fail.c:30
UV_RUN_DEFAULT
@ UV_RUN_DEFAULT
Definition: uv.h:254
uv_udp_s
Definition: uv.h:629
loop
static uv_loop_t * loop
Definition: test-getsockname.c:36
uv_shutdown
UV_PRIVATE_REQ_TYPES UV_EXTERN int uv_shutdown(uv_shutdown_t *req, uv_stream_t *handle, uv_shutdown_cb cb)
Definition: unix/stream.c:1259
server_port
static const int server_port
Definition: test-getsockname.c:29
uv_read_start
UV_EXTERN int uv_read_start(uv_stream_t *, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
Definition: unix/stream.c:1555
alloc
static void alloc(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
Definition: test-getsockname.c:45
uv_tcp_init
UV_EXTERN int uv_tcp_init(uv_loop_t *, uv_tcp_t *handle)
Definition: unix/tcp.c:143
uv_accept
UV_EXTERN int uv_accept(uv_stream_t *server, uv_stream_t *client)
Definition: unix/stream.c:591
on_close
static void on_close(uv_handle_t *peer)
Definition: test-getsockname.c:51
uv_ip4_name
UV_EXTERN int uv_ip4_name(const struct sockaddr_in *src, char *dst, size_t size)
Definition: uv-common.c:267
uv_tcp_s
Definition: uv.h:544
uv_udp_send_s
Definition: uv.h:645
udp
static uv_udp_t udp
Definition: test-getsockname.c:38
uv.h
getsocknamecount
static int getsocknamecount
Definition: test-getsockname.c:33
uv_udp_recv_start
UV_EXTERN int uv_udp_recv_start(uv_udp_t *handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb)
Definition: uv-common.c:438
MAKE_VALGRIND_HAPPY
#define MAKE_VALGRIND_HAPPY()
Definition: task.h:229
uv_buf_t
Definition: unix.h:121
uv_udp_s::send_queue_size
UV_HANDLE_FIELDS size_t send_queue_size
Definition: uv.h:636
uv_udp_bind
UV_EXTERN int uv_udp_bind(uv_udp_t *handle, const struct sockaddr *addr, unsigned int flags)
Definition: uv-common.c:296
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
server
Definition: examples/python/async_streaming/server.py:1
check_sockname
static void check_sockname(struct sockaddr *addr, const char *compare_ip, int compare_port, const char *context)
Definition: test-getsockname.c:79
fix_build_deps.r
r
Definition: fix_build_deps.py:491
uv_buf_init
UV_EXTERN uv_buf_t uv_buf_init(char *base, unsigned int len)
Definition: uv-common.c:157
after_read
static void after_read(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf)
Definition: test-getsockname.c:63
on_connect
static void on_connect(uv_connect_t *req, int status)
Definition: test-getsockname.c:147
on_connection
static void on_connection(uv_stream_t *server, int status)
Definition: test-getsockname.c:107
handle
static csh handle
Definition: test_arm_regression.c:16
connect_req
static uv_connect_t connect_req
Definition: test-getsockname.c:39
context
grpc::ClientContext context
Definition: istio_echo_server_lib.cc:61
uv_handle_s
Definition: uv.h:441
uv_loop_s
Definition: uv.h:1767
tcp
static uv_tcp_t tcp
Definition: test-getsockname.c:37
uv_err_name
const UV_EXTERN char * uv_err_name(int err)
Definition: uv-common.c:189
send_req
static uv_udp_send_t send_req
Definition: test-getsockname.c:42
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:26