diff options
| author | 2023-09-04 11:13:40 +0200 | |
|---|---|---|
| committer | 2023-09-04 11:13:40 +0200 | |
| commit | 18c11ab9167ed870da0919418422134b1d1b69fc (patch) | |
| tree | c24f6ddcc21a18e6e89fe5fad13578632441ba46 /xs_socket.h | |
| parent | Backport from xs. (diff) | |
| download | snac2-18c11ab9167ed870da0919418422134b1d1b69fc.tar.gz snac2-18c11ab9167ed870da0919418422134b1d1b69fc.tar.xz snac2-18c11ab9167ed870da0919418422134b1d1b69fc.zip | |
Backport from xs.
Diffstat (limited to 'xs_socket.h')
| -rw-r--r-- | xs_socket.h | 90 |
1 files changed, 86 insertions, 4 deletions
diff --git a/xs_socket.h b/xs_socket.h index 42a2d25..a2f9cb6 100644 --- a/xs_socket.h +++ b/xs_socket.h | |||
| @@ -5,9 +5,11 @@ | |||
| 5 | #define _XS_SOCKET_H | 5 | #define _XS_SOCKET_H |
| 6 | 6 | ||
| 7 | int xs_socket_timeout(int s, double rto, double sto); | 7 | int xs_socket_timeout(int s, double rto, double sto); |
| 8 | int xs_socket_server_serv(const char *addr, const char *serv); | ||
| 8 | int xs_socket_server(const char *addr, int port); | 9 | int xs_socket_server(const char *addr, int port); |
| 9 | FILE *xs_socket_accept(int rs); | 10 | FILE *xs_socket_accept(int rs); |
| 10 | xs_str *xs_socket_peername(int s); | 11 | xs_str *xs_socket_peername(int s); |
| 12 | int xs_socket_connect(const char *addr, const char *serv); | ||
| 11 | 13 | ||
| 12 | 14 | ||
| 13 | #ifdef XS_IMPLEMENTATION | 15 | #ifdef XS_IMPLEMENTATION |
| @@ -42,8 +44,8 @@ int xs_socket_timeout(int s, double rto, double sto) | |||
| 42 | } | 44 | } |
| 43 | 45 | ||
| 44 | 46 | ||
| 45 | int xs_socket_server(const char *addr, int port) | 47 | int xs_socket_server_serv(const char *addr, const char *serv) |
| 46 | /* opens a server socket */ | 48 | /* opens a server socket by service name (or port as string) */ |
| 47 | { | 49 | { |
| 48 | int rs = -1; | 50 | int rs = -1; |
| 49 | struct sockaddr_in host; | 51 | struct sockaddr_in host; |
| @@ -59,8 +61,14 @@ int xs_socket_server(const char *addr, int port) | |||
| 59 | goto end; | 61 | goto end; |
| 60 | } | 62 | } |
| 61 | 63 | ||
| 64 | struct servent *se; | ||
| 65 | |||
| 66 | if ((se = getservbyname(serv, "tcp")) != NULL) | ||
| 67 | host.sin_port = se->s_port; | ||
| 68 | else | ||
| 69 | host.sin_port = htons(atoi(serv)); | ||
| 70 | |||
| 62 | host.sin_family = AF_INET; | 71 | host.sin_family = AF_INET; |
| 63 | host.sin_port = htons(port); | ||
| 64 | 72 | ||
| 65 | if ((rs = socket(AF_INET, SOCK_STREAM, 0)) != -1) { | 73 | if ((rs = socket(AF_INET, SOCK_STREAM, 0)) != -1) { |
| 66 | /* reuse addr */ | 74 | /* reuse addr */ |
| @@ -80,6 +88,16 @@ end: | |||
| 80 | } | 88 | } |
| 81 | 89 | ||
| 82 | 90 | ||
| 91 | int xs_socket_server(const char *addr, int port) | ||
| 92 | /* opens a server socket (port as integer) */ | ||
| 93 | { | ||
| 94 | char serv[32]; | ||
| 95 | |||
| 96 | snprintf(serv, sizeof(serv), "%d", port); | ||
| 97 | return xs_socket_server_serv(addr, serv); | ||
| 98 | } | ||
| 99 | |||
| 100 | |||
| 83 | FILE *xs_socket_accept(int rs) | 101 | FILE *xs_socket_accept(int rs) |
| 84 | /* accepts an incoming connection */ | 102 | /* accepts an incoming connection */ |
| 85 | { | 103 | { |
| @@ -124,6 +142,70 @@ xs_str *xs_socket_peername(int s) | |||
| 124 | } | 142 | } |
| 125 | 143 | ||
| 126 | 144 | ||
| 145 | int xs_socket_connect(const char *addr, const char *serv) | ||
| 146 | /* creates a client connection socket */ | ||
| 147 | { | ||
| 148 | int d = -1; | ||
| 149 | |||
| 150 | #ifndef WITHOUT_GETADDRINFO | ||
| 151 | struct addrinfo *res; | ||
| 152 | struct addrinfo hints; | ||
| 153 | |||
| 154 | memset(&hints, '\0', sizeof(hints)); | ||
| 155 | |||
| 156 | hints.ai_socktype = SOCK_STREAM; | ||
| 157 | hints.ai_flags = AI_ADDRCONFIG; | ||
| 158 | |||
| 159 | if (getaddrinfo(addr, serv, &hints, &res) == 0) { | ||
| 160 | struct addrinfo *r; | ||
| 161 | |||
| 162 | for (r = res; r != NULL; r = r->ai_next) { | ||
| 163 | d = socket(r->ai_family, r->ai_socktype, r->ai_protocol); | ||
| 164 | |||
| 165 | if (d != -1) { | ||
| 166 | if (connect(d, r->ai_addr, r->ai_addrlen) == 0) | ||
| 167 | break; | ||
| 168 | |||
| 169 | close(d); | ||
| 170 | d = -1; | ||
| 171 | } | ||
| 172 | } | ||
| 173 | |||
| 174 | freeaddrinfo(res); | ||
| 175 | } | ||
| 176 | |||
| 177 | #else /* WITHOUT_GETADDRINFO */ | ||
| 178 | |||
| 179 | /* traditional socket interface */ | ||
| 180 | struct hostent *he; | ||
| 181 | |||
| 182 | if ((he = gethostbyname(addr)) != NULL) { | ||
| 183 | struct sockaddr_in host; | ||
| 184 | |||
| 185 | memset(&host, '\0', sizeof(host)); | ||
| 186 | |||
| 187 | memcpy(&host.sin_addr, he->h_addr_list[0], he->h_length); | ||
| 188 | host.sin_family = he->h_addrtype; | ||
| 189 | |||
| 190 | struct servent *se; | ||
| 191 | |||
| 192 | if ((se = getservbyname(serv, "tcp")) != NULL) | ||
| 193 | host.sin_port = se->s_port; | ||
| 194 | else | ||
| 195 | host.sin_port = htons(atoi(serv)); | ||
| 196 | |||
| 197 | if ((d = socket(AF_INET, SOCK_STREAM, 0)) != -1) { | ||
| 198 | if (connect(d, (struct sockaddr *)&host, sizeof(host)) == -1) | ||
| 199 | d = -1; | ||
| 200 | } | ||
| 201 | } | ||
| 202 | |||
| 203 | #endif /* WITHOUT_GETADDRINFO */ | ||
| 204 | |||
| 205 | return d; | ||
| 206 | } | ||
| 207 | |||
| 208 | |||
| 127 | #endif /* XS_IMPLEMENTATION */ | 209 | #endif /* XS_IMPLEMENTATION */ |
| 128 | 210 | ||
| 129 | #endif /* _XS_SOCKET_H */ \ No newline at end of file | 211 | #endif /* _XS_SOCKET_H */ |