commit 18c11ab
default
·
2023-09-04 09:13:40 +0000 UTC
parent 8535fc8
Backport from xs.
2 files changed,
+87,
-5
+86,
-4
1@@ -5,9 +5,11 @@
2 #define _XS_SOCKET_H
3
4 int xs_socket_timeout(int s, double rto, double sto);
5+int xs_socket_server_serv(const char *addr, const char *serv);
6 int xs_socket_server(const char *addr, int port);
7 FILE *xs_socket_accept(int rs);
8 xs_str *xs_socket_peername(int s);
9+int xs_socket_connect(const char *addr, const char *serv);
10
11
12 #ifdef XS_IMPLEMENTATION
13@@ -42,8 +44,8 @@ int xs_socket_timeout(int s, double rto, double sto)
14 }
15
16
17-int xs_socket_server(const char *addr, int port)
18-/* opens a server socket */
19+int xs_socket_server_serv(const char *addr, const char *serv)
20+/* opens a server socket by service name (or port as string) */
21 {
22 int rs = -1;
23 struct sockaddr_in host;
24@@ -59,8 +61,14 @@ int xs_socket_server(const char *addr, int port)
25 goto end;
26 }
27
28+ struct servent *se;
29+
30+ if ((se = getservbyname(serv, "tcp")) != NULL)
31+ host.sin_port = se->s_port;
32+ else
33+ host.sin_port = htons(atoi(serv));
34+
35 host.sin_family = AF_INET;
36- host.sin_port = htons(port);
37
38 if ((rs = socket(AF_INET, SOCK_STREAM, 0)) != -1) {
39 /* reuse addr */
40@@ -80,6 +88,16 @@ end:
41 }
42
43
44+int xs_socket_server(const char *addr, int port)
45+/* opens a server socket (port as integer) */
46+{
47+ char serv[32];
48+
49+ snprintf(serv, sizeof(serv), "%d", port);
50+ return xs_socket_server_serv(addr, serv);
51+}
52+
53+
54 FILE *xs_socket_accept(int rs)
55 /* accepts an incoming connection */
56 {
57@@ -124,6 +142,70 @@ xs_str *xs_socket_peername(int s)
58 }
59
60
61+int xs_socket_connect(const char *addr, const char *serv)
62+/* creates a client connection socket */
63+{
64+ int d = -1;
65+
66+#ifndef WITHOUT_GETADDRINFO
67+ struct addrinfo *res;
68+ struct addrinfo hints;
69+
70+ memset(&hints, '\0', sizeof(hints));
71+
72+ hints.ai_socktype = SOCK_STREAM;
73+ hints.ai_flags = AI_ADDRCONFIG;
74+
75+ if (getaddrinfo(addr, serv, &hints, &res) == 0) {
76+ struct addrinfo *r;
77+
78+ for (r = res; r != NULL; r = r->ai_next) {
79+ d = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
80+
81+ if (d != -1) {
82+ if (connect(d, r->ai_addr, r->ai_addrlen) == 0)
83+ break;
84+
85+ close(d);
86+ d = -1;
87+ }
88+ }
89+
90+ freeaddrinfo(res);
91+ }
92+
93+#else /* WITHOUT_GETADDRINFO */
94+
95+ /* traditional socket interface */
96+ struct hostent *he;
97+
98+ if ((he = gethostbyname(addr)) != NULL) {
99+ struct sockaddr_in host;
100+
101+ memset(&host, '\0', sizeof(host));
102+
103+ memcpy(&host.sin_addr, he->h_addr_list[0], he->h_length);
104+ host.sin_family = he->h_addrtype;
105+
106+ struct servent *se;
107+
108+ if ((se = getservbyname(serv, "tcp")) != NULL)
109+ host.sin_port = se->s_port;
110+ else
111+ host.sin_port = htons(atoi(serv));
112+
113+ if ((d = socket(AF_INET, SOCK_STREAM, 0)) != -1) {
114+ if (connect(d, (struct sockaddr *)&host, sizeof(host)) == -1)
115+ d = -1;
116+ }
117+ }
118+
119+#endif /* WITHOUT_GETADDRINFO */
120+
121+ return d;
122+}
123+
124+
125 #endif /* XS_IMPLEMENTATION */
126
127-#endif /* _XS_SOCKET_H */
128+#endif /* _XS_SOCKET_H */
+1,
-1
1@@ -1 +1 @@
2-/* 9a2b91d7713c862ce8753721da2ab5867abb80fd */
3+/* fdd04f1862e0d8bdebb7b438798914643895d43f */