#include <atalk/dsi.h>
#include <atalk/compat.h>
#include <atalk/util.h>
-
-#include "dsi_private.h"
+#include <atalk/errchk.h>
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif
/* this needs to accept passed in addresses */
-int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address,
- const char *port, const int proxy)
+int dsi_tcp_init(DSI *dsi, const char *hostname, const char *inaddress, const char *inport)
{
- int ret;
+ EC_INIT;
int flag;
+ char *a = NULL, *b;
+ const char *address;
+ const char *port;
struct addrinfo hints, *servinfo, *p;
- dsi->protocol = DSI_TCPIP;
+ /* Check whether address is of the from IP:PORT and split */
+ address = inaddress;
+ port = inport;
+ if (address && strchr(address, ':')) {
+ EC_NULL_LOG( address = a = strdup(address) );
+ b = strchr(a, ':');
+ *b = 0;
+ port = b + 1;
+ }
/* Prepare hint for getaddrinfo */
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
#endif
}
- if ((ret = getaddrinfo(address ? address : NULL, port ? port : "548", &hints, &servinfo)) != 0) {
+ if ((ret = getaddrinfo(address ? address : NULL, port, &hints, &servinfo)) != 0) {
LOG(log_error, logtype_dsi, "dsi_tcp_init: getaddrinfo: %s\n", gai_strerror(ret));
- return 0;
+ EC_FAIL;
}
- /* create a socket */
- if (proxy)
- dsi->serversock = -1;
- else {
- /* loop through all the results and bind to the first we can */
- for (p = servinfo; p != NULL; p = p->ai_next) {
- if ((dsi->serversock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
- LOG(log_info, logtype_dsi, "dsi_tcp_init: socket: %s", strerror(errno));
- continue;
- }
+ /* loop through all the results and bind to the first we can */
+ for (p = servinfo; p != NULL; p = p->ai_next) {
+ if ((dsi->serversock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
+ LOG(log_info, logtype_dsi, "dsi_tcp_init: socket: %s", strerror(errno));
+ continue;
+ }
- /*
- * Set some socket options:
- * SO_REUSEADDR deals w/ quick close/opens
- * TCP_NODELAY diables Nagle
- */
+ /*
+ * Set some socket options:
+ * SO_REUSEADDR deals w/ quick close/opens
+ * TCP_NODELAY diables Nagle
+ */
#ifdef SO_REUSEADDR
- flag = 1;
- setsockopt(dsi->serversock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
+ flag = 1;
+ setsockopt(dsi->serversock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
#endif
#if defined(FREEBSD) && defined(IPV6_BINDV6ONLY)
- int on = 0;
- setsockopt(dsi->serversock, IPPROTO_IPV6, IPV6_BINDV6ONLY, (char *)&on, sizeof (on));
+ int on = 0;
+ setsockopt(dsi->serversock, IPPROTO_IPV6, IPV6_BINDV6ONLY, (char *)&on, sizeof (on));
#endif
#ifdef USE_TCP_NODELAY
#ifndef SOL_TCP
#define SOL_TCP IPPROTO_TCP
#endif
- flag = 1;
- setsockopt(dsi->serversock, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag));
+ flag = 1;
+ setsockopt(dsi->serversock, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag));
#endif /* USE_TCP_NODELAY */
- if (bind(dsi->serversock, p->ai_addr, p->ai_addrlen) == -1) {
- close(dsi->serversock);
- LOG(log_info, logtype_dsi, "dsi_tcp_init: bind: %s\n", strerror(errno));
- continue;
- }
-
- if (listen(dsi->serversock, DSI_TCPMAXPEND) < 0) {
- close(dsi->serversock);
- LOG(log_info, logtype_dsi, "dsi_tcp_init: listen: %s\n", strerror(errno));
- continue;
- }
-
- break;
+ if (bind(dsi->serversock, p->ai_addr, p->ai_addrlen) == -1) {
+ close(dsi->serversock);
+ LOG(log_info, logtype_dsi, "dsi_tcp_init: bind: %s\n", strerror(errno));
+ continue;
}
- if (p == NULL) {
- LOG(log_error, logtype_dsi, "dsi_tcp_init: no suitable network config for TCP socket");
- freeaddrinfo(servinfo);
- return 0;
+ if (listen(dsi->serversock, DSI_TCPMAXPEND) < 0) {
+ close(dsi->serversock);
+ LOG(log_info, logtype_dsi, "dsi_tcp_init: listen: %s\n", strerror(errno));
+ continue;
}
+
+ break;
+ }
- /* Copy struct sockaddr to struct sockaddr_storage */
- memcpy(&dsi->server, p->ai_addr, p->ai_addrlen);
+ if (p == NULL) {
+ LOG(log_error, logtype_dsi, "dsi_tcp_init: no suitable network config for TCP socket");
freeaddrinfo(servinfo);
- } /* if (proxy) */
+ EC_FAIL;
+ }
+
+ /* Copy struct sockaddr to struct sockaddr_storage */
+ memcpy(&dsi->server, p->ai_addr, p->ai_addrlen);
+ freeaddrinfo(servinfo);
/* Point protocol specific functions to tcp versions */
dsi->proto_open = dsi_tcp_open;
if (address) {
/* address is a parameter, use it 'as is' */
- return 1;
+ goto EC_CLEANUP;
}
/* Prepare hint for getaddrinfo */
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
- if ((ret = getaddrinfo(hostname, port ? port : "548", &hints, &servinfo)) != 0) {
+ if ((ret = getaddrinfo(hostname, port, &hints, &servinfo)) != 0) {
LOG(log_info, logtype_dsi, "dsi_tcp_init: getaddrinfo '%s': %s\n", hostname, gai_strerror(ret));
goto interfaces;
}
/* Store found address in dsi->server */
memcpy(&dsi->server, p->ai_addr, p->ai_addrlen);
freeaddrinfo(servinfo);
- return 1;
+ goto EC_CLEANUP;
}
LOG(log_info, logtype_dsi, "dsi_tcp: hostname '%s' resolves to loopback address", hostname);
freeaddrinfo(servinfo);
interfaces:
guess_interface(dsi, hostname, port ? port : "548");
- return 1;
+
+EC_CLEANUP:
+ if (a)
+ free(a);
+ EC_EXIT;
}