|
@@ -3,6 +3,16 @@
|
|
|
* Copyright (C) 2005-2007 Takahiro Hirofuchi
|
|
|
*/
|
|
|
|
|
|
+#include <sys/socket.h>
|
|
|
+#include <arpa/inet.h>
|
|
|
+
|
|
|
+#include <string.h>
|
|
|
+
|
|
|
+#include <netdb.h>
|
|
|
+#include <netinet/tcp.h>
|
|
|
+#include <unistd.h>
|
|
|
+
|
|
|
+#include "usbip_common.h"
|
|
|
#include "usbip_network.h"
|
|
|
|
|
|
void pack_uint32_t(int pack, uint32_t *num)
|
|
@@ -186,66 +196,49 @@ int usbip_set_keepalive(int sockfd)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-/* IPv6 Ready */
|
|
|
/*
|
|
|
- * moved here from vhci_attach.c
|
|
|
+ * IPv6 Ready
|
|
|
*/
|
|
|
-int tcp_connect(char *hostname, char *service)
|
|
|
+int usbip_net_tcp_connect(char *hostname, char *port)
|
|
|
{
|
|
|
- struct addrinfo hints, *res, *res0;
|
|
|
+ struct addrinfo hints, *res, *rp;
|
|
|
int sockfd;
|
|
|
- int err;
|
|
|
-
|
|
|
+ int ret;
|
|
|
|
|
|
memset(&hints, 0, sizeof(hints));
|
|
|
+ hints.ai_family = AF_UNSPEC;
|
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
|
|
|
|
/* get all possible addresses */
|
|
|
- err = getaddrinfo(hostname, service, &hints, &res0);
|
|
|
- if (err) {
|
|
|
- err("%s %s: %s", hostname, service, gai_strerror(err));
|
|
|
- return -1;
|
|
|
+ ret = getaddrinfo(hostname, port, &hints, &res);
|
|
|
+ if (ret < 0) {
|
|
|
+ dbg("getaddrinfo: %s port %s: %s", hostname, port,
|
|
|
+ gai_strerror(ret));
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
- /* try all the addresses */
|
|
|
- for (res = res0; res; res = res->ai_next) {
|
|
|
- char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
|
|
|
-
|
|
|
- err = getnameinfo(res->ai_addr, res->ai_addrlen,
|
|
|
- hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);
|
|
|
- if (err) {
|
|
|
- err("%s %s: %s", hostname, service, gai_strerror(err));
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- dbg("trying %s port %s\n", hbuf, sbuf);
|
|
|
-
|
|
|
- sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
|
|
- if (sockfd < 0) {
|
|
|
- err("socket");
|
|
|
+ /* try the addresses */
|
|
|
+ for (rp = res; rp; rp = rp->ai_next) {
|
|
|
+ sockfd = socket(rp->ai_family, rp->ai_socktype,
|
|
|
+ rp->ai_protocol);
|
|
|
+ if (sockfd < 0)
|
|
|
continue;
|
|
|
- }
|
|
|
|
|
|
/* should set TCP_NODELAY for usbip */
|
|
|
usbip_set_nodelay(sockfd);
|
|
|
- /* TODO: write code for heatbeat */
|
|
|
+ /* TODO: write code for heartbeat */
|
|
|
usbip_set_keepalive(sockfd);
|
|
|
|
|
|
- err = connect(sockfd, res->ai_addr, res->ai_addrlen);
|
|
|
- if (err < 0) {
|
|
|
- close(sockfd);
|
|
|
- continue;
|
|
|
- }
|
|
|
+ if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) == 0)
|
|
|
+ break;
|
|
|
|
|
|
- /* connected */
|
|
|
- dbg("connected to %s:%s", hbuf, sbuf);
|
|
|
- freeaddrinfo(res0);
|
|
|
- return sockfd;
|
|
|
+ close(sockfd);
|
|
|
}
|
|
|
|
|
|
+ if (!rp)
|
|
|
+ return EAI_SYSTEM;
|
|
|
|
|
|
- dbg("%s:%s, %s", hostname, service, "no destination to connect to");
|
|
|
- freeaddrinfo(res0);
|
|
|
+ freeaddrinfo(res);
|
|
|
|
|
|
- return -1;
|
|
|
+ return sockfd;
|
|
|
}
|