src/server/util/socket.c

Sun, 15 Feb 2026 13:30:29 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 15 Feb 2026 13:30:29 +0100
changeset 674
6a031133a498
parent 673
144bdc33fdb6
permissions
-rw-r--r--

add http_client_send_request test

673
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2026 Olaf Wintermann. All rights reserved.
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 *
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 *
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 *
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
29 #include "socket.h"
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
30
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
31 #include <unistd.h>
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
32 #include <sys/fcntl.h>
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
33 #include <sys/socket.h>
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
34 #include <netinet/in.h>
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
35 #include <arpa/inet.h>
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
36
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
37 int util_server_socket_local(short *port) {
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
38 int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
39 if(socket_fd < 0) {
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
40 return -1;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
41 }
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
42
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
43 short socket_port = 0;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
44 if(port) {
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
45 socket_port = *port;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
46 }
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
47
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
48 struct sockaddr_in addr;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
49 addr.sin_family = AF_INET;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
50 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
51 addr.sin_port = htons(socket_port);
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
52
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
53 if(bind(socket_fd, (struct sockaddr*)&addr, sizeof(addr))) {
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
54 close(socket_fd);
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
55 return -1;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
56 }
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
57
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
58 socklen_t len = sizeof(addr);
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
59 if(getsockname(socket_fd, (struct sockaddr *)&addr, &len) < 0) {
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
60 close(socket_fd);
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
61 return -1;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
62 }
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
63
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
64 if(port) {
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
65 *port = ntohs(addr.sin_port);
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
66 }
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
67
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
68 return socket_fd;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
69 }
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
70
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
71 int util_socket_connect_local(short port) {
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
72 int fd = socket(AF_INET, SOCK_STREAM, 0);
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
73 if(fd < 0) {
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
74 return -1;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
75 }
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
76
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
77 struct sockaddr_in addr;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78 addr.sin_family = AF_INET;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
80 addr.sin_port = htons(port);
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
81
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
82 if(connect(fd, (struct sockaddr*)&addr, sizeof(addr))) {
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
83 close(fd);
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
84 return -1;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85 }
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
86
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
87 return fd;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
88 }
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
89
674
6a031133a498 add http_client_send_request test
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 673
diff changeset
90 int util_socketpair(int fds[2]) {
6a031133a498 add http_client_send_request test
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 673
diff changeset
91 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) {
6a031133a498 add http_client_send_request test
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 673
diff changeset
92 fds[0] = -1;
6a031133a498 add http_client_send_request test
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 673
diff changeset
93 fds[1] = -1;
6a031133a498 add http_client_send_request test
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 673
diff changeset
94 return -1;
6a031133a498 add http_client_send_request test
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 673
diff changeset
95 }
6a031133a498 add http_client_send_request test
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 673
diff changeset
96 return 0;
6a031133a498 add http_client_send_request test
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 673
diff changeset
97 }
6a031133a498 add http_client_send_request test
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 673
diff changeset
98
673
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99 int util_socket_setnonblock(int fd, int nonblock) {
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 int flags;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101 if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102 flags = 0;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
103 }
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104 if(nonblock) {
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
105 flags |= O_NONBLOCK;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
106 } else {
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
107 flags &= ~O_NONBLOCK;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108 }
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
109 if (fcntl(fd, F_SETFL, flags) != 0) {
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
110 return 1;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
111 }
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
112 return 0;
144bdc33fdb6 add socket utils
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
113 }

mercurial