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 */