75
76
errno = WSAGetLastError();
78
freelog(LOG_ERROR, "Missing errno mapping for Winsock error #%d. "
79
"Please report this message at %s.",
80
WSAGetLastError(), BUG_URL);
80
"Missing errno mapping for Winsock error #%d.",
83
/* TRANS: No full stop after the URL, could cause confusion. */
84
_("Please report this message at %s"),
88
#endif /* HAVE_WINSOCK */
85
90
/***************************************************************
86
91
Connect a socket to an address
87
92
***************************************************************/
88
int my_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
93
int fc_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
214
223
if ((f_set=fcntl(sockfd, F_GETFL)) == -1) {
215
freelog(LOG_ERROR, "fcntl F_GETFL failed: %s", mystrerror());
224
freelog(LOG_ERROR, "fcntl F_GETFL failed: %s", fc_strerror(fc_get_errno()));
218
227
f_set |= O_NONBLOCK;
220
229
if (fcntl(sockfd, F_SETFL, f_set) == -1) {
221
freelog(LOG_ERROR, "fcntl F_SETFL failed: %s", mystrerror());
230
freelog(LOG_ERROR, "fcntl F_SETFL failed: %s", fc_strerror(fc_get_errno()));
224
233
#ifdef HAVE_IOCTL
227
236
if (ioctl(sockfd, FIONBIO, (char*)&value) == -1) {
228
freelog(LOG_ERROR, "ioctl failed: %s", mystrerror());
237
freelog(LOG_ERROR, "ioctl failed: %s", fc_strerror(fc_get_errno()));
238
247
/***************************************************************************
248
Write information about socaddr to debug log.
249
***************************************************************************/
250
void sockaddr_debug(union fc_sockaddr *addr)
253
char buf[INET6_ADDRSTRLEN] = "Unknown";
255
if (addr->saddr.sa_family == AF_INET6) {
256
inet_ntop(AF_INET6, &addr->saddr_in6.sin6_addr, buf, INET6_ADDRSTRLEN);
257
freelog(LOG_DEBUG, "Host: %s, Port: %d (IPv6)",
258
buf, ntohs(addr->saddr_in6.sin6_port));
260
inet_ntop(AF_INET, &addr->saddr_in4.sin_addr, buf, INET_ADDRSTRLEN);
261
freelog(LOG_DEBUG, "Host: %s, Port: %d (IPv4)",
262
buf, ntohs(addr->saddr_in4.sin_port));
264
#else /* IPv6 support */
267
buf = inet_ntoa(addr->saddr_in4.sin_addr);
269
freelog(LOG_DEBUG, "Host: %s, Port: %d",
270
buf, ntohs(addr->saddr_in4.sin_port));
271
#endif /* IPv6 support */
274
/***************************************************************************
275
Gets size of address to fc_sockaddr. IPv6/IPv4 must be selected before
277
***************************************************************************/
278
int sockaddr_size(union fc_sockaddr *addr)
281
if (addr->saddr.sa_family == AF_INET6) {
282
return sizeof(addr->saddr_in6);
284
#endif /* IPV6_SUPPORT */
286
return sizeof(addr->saddr_in4);
290
/***************************************************************************
291
Returns wether address is IPv6 address.
292
***************************************************************************/
293
bool sockaddr_ipv6(union fc_sockaddr *addr)
296
if (addr->saddr.sa_family == AF_INET6) {
299
#endif /* IPv6 support */
305
/***************************************************************************
239
306
Look up the service at hostname:port and fill in *sa.
240
307
***************************************************************************/
241
bool net_lookup_service(const char *name, int port, union my_sockaddr *addr)
308
bool net_lookup_service(const char *name, int port, union fc_sockaddr *addr,
243
311
struct hostent *hp;
244
struct sockaddr_in *sock = &addr->sockaddr_in;
246
sock->sin_family = AF_INET;
247
sock->sin_port = htons(port);
250
sock->sin_addr.s_addr = htonl(INADDR_ANY);
254
#ifdef HAVE_INET_ATON
255
if (inet_aton(name, &sock->sin_addr) != 0) {
259
if ((sock->sin_addr.s_addr = inet_addr(name)) != INADDR_NONE) {
312
struct sockaddr_in *sock4;
314
struct sockaddr_in6 *sock6;
315
#endif /* IPv6 support */
317
sock4 = &addr->saddr_in4;
320
sock6 = &addr->saddr_in6;
323
addr->saddr.sa_family = AF_INET6;
324
sock6->sin6_port = htons(port);
327
sock6->sin6_addr = in6addr_any;
331
if (inet_pton(AF_INET6, name, &sock6->sin6_addr)) {
334
/* TODO: Replace gethostbyname2() with getaddrinfo() */
335
hp = gethostbyname2(name, AF_INET6);
337
#endif /* IPv6 support */
339
addr->saddr.sa_family = AF_INET;
340
sock4->sin_port = htons(port);
343
sock4->sin_addr.s_addr = htonl(INADDR_ANY);
349
if (force_ipv4 || !hp || hp->h_addrtype != AF_INET6) {
350
/* Try to fallback to IPv4 resolution */
352
freelog(LOG_DEBUG, "Falling back to IPv4");
354
hp = gethostbyname2(name, AF_INET);
355
if (!hp || hp->h_addrtype != AF_INET) {
358
addr->saddr.sa_family = AF_INET;
359
sock4->sin_port = htons(port);
361
#else /* IPV6 support */
362
#if defined(HAVE_INET_ATON)
363
if (inet_aton(name, &sock4->sin_addr) != 0) {
366
#else /* HAVE_INET_ATON */
367
if ((sock4->sin_addr.s_addr = inet_addr(name)) != INADDR_NONE) {
370
#endif /* HAVE_INET_ATON */
263
371
hp = gethostbyname(name);
264
372
if (!hp || hp->h_addrtype != AF_INET) {
268
memcpy(&sock->sin_addr, hp->h_addr, hp->h_length);
375
#endif /* IPv6 support */
378
if (addr->saddr.sa_family == AF_INET6) {
379
memcpy(&sock6->sin6_addr, hp->h_addr, hp->h_length);
381
#endif /* IPv6 support */
383
memcpy(&sock4->sin_addr, hp->h_addr, hp->h_length);
354
473
str += strlen("http://");
356
pport = strchr(str, ':');
357
ppath = strchr(str, '/');
476
/* Literal IPv6 address (RFC 2732) */
478
str2 = strchr(str, ']') + 1;
480
str2 = str + strlen(str);
487
pport = strchr(str2, ':');
488
ppath = strchr(str2, '/');
359
490
/* snarf server. */
360
491
server[0] = '\0';
363
strncat(server, str, MIN(MAX_LEN_ADDR, pport-str));
494
strncat(server, str, MIN(MAX_LEN_ADDR, pport-str-chars_between));
366
strncat(server, str, MIN(MAX_LEN_ADDR, ppath-str));
497
strncat(server, str, MIN(MAX_LEN_ADDR, ppath-str-chars_between));
368
499
strncat(server, str, MAX_LEN_ADDR);