summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2010-02-25 14:52:36 +0100
committerIzik Eidus <ieidus@redhat.com>2010-02-27 22:12:08 +0200
commit872be6b2d787ce0772beb7a5f741e14ed373ef86 (patch)
tree57e27ddbdf4b96f45e1ffdd042aaab818d2078fc
parent878c215501825cf3cd17a399b5e7dce79957f1ab (diff)
spice client: add ipv6 support.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r--client/red_peer.cpp92
-rw-r--r--client/red_peer.h2
2 files changed, 41 insertions, 53 deletions
diff --git a/client/red_peer.cpp b/client/red_peer.cpp
index 7534c3e..ce6ec0e 100644
--- a/client/red_peer.cpp
+++ b/client/red_peer.cpp
@@ -69,64 +69,54 @@ void RedPeer::cleanup()
}
}
-uint32_t RedPeer::host_by_name(const char* host)
+void RedPeer::connect_unsecure(const char* host, int portnr)
{
- struct addrinfo *e, *result = NULL;
- struct sockaddr_in *addr;
- uint32_t return_value;
- int rc;
-
- rc = getaddrinfo(host, NULL, NULL, &result);
- for (e = result; e != NULL; e = e->ai_next) {
- if (e->ai_family == PF_INET)
- break;
- }
- if (rc != 0 || e == NULL) {
- if (result)
- freeaddrinfo(result);
- THROW_ERR(SPICEC_ERROR_CODE_GETHOSTBYNAME_FAILED, "cannot resolve host address %s", host);
- }
-
- addr = (sockaddr_in *)e->ai_addr;
- return_value = addr->sin_addr.s_addr;
-
- freeaddrinfo(result);
-
- DBG(0, "%s = %u", host, return_value);
- return ntohl(return_value);
-}
-
-void RedPeer::connect_unsecure(const char* host, int port)
-{
- struct sockaddr_in addr;
- int no_delay;
- uint32_t ip;
+ struct addrinfo ai, *result = NULL, *e;
+ char uaddr[INET6_ADDRSTRLEN+1];
+ char uport[33], port[33];
+ int err = 0, rc, no_delay = 1;
ASSERT(_ctx == NULL && _ssl == NULL && _peer == INVALID_SOCKET);
try {
- ip = host_by_name(host);
-
- addr.sin_port = htons(port);
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl(ip);
-
- Lock lock(_lock);
- if ((_peer = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
- int err = sock_error();
- THROW_ERR(SPICEC_ERROR_CODE_SOCKET_FAILED, "failed to create socket: %s (%d)",
- sock_err_message(err), err);
+ memset(&ai,0, sizeof(ai));
+ ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
+ ai.ai_family = PF_UNSPEC;
+ ai.ai_socktype = SOCK_STREAM;
+ snprintf(port, sizeof(port), "%d", portnr);
+ rc = getaddrinfo(host, port, &ai, &result);
+ if (rc != 0) {
+ THROW_ERR(SPICEC_ERROR_CODE_GETHOSTBYNAME_FAILED, "cannot resolve host address %s", host);
}
+ Lock lock(_lock);
+ _peer = -1;
+ for (e = result; e != NULL; e = e->ai_next) {
+ if ((_peer = socket(e->ai_family, e->ai_socktype, e->ai_protocol)) == INVALID_SOCKET) {
+ int err = sock_error();
+ THROW_ERR(SPICEC_ERROR_CODE_SOCKET_FAILED, "failed to create socket: %s (%d)",
+ sock_err_message(err), err);
+ }
+ if (setsockopt(_peer, IPPROTO_TCP, TCP_NODELAY, (const char*)&no_delay, sizeof(no_delay)) ==
+ SOCKET_ERROR) {
+ LOG_WARN("set TCP_NODELAY failed");
+ }
- no_delay = 1;
- if (setsockopt(_peer, IPPROTO_TCP, TCP_NODELAY, (const char*)&no_delay, sizeof(no_delay)) ==
- SOCKET_ERROR) {
- LOG_WARN("set TCP_NODELAY failed");
+ getnameinfo((struct sockaddr*)e->ai_addr, e->ai_addrlen,
+ uaddr,INET6_ADDRSTRLEN, uport,32,
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ LOG_INFO("Trying %s %s", uaddr, uport);
+ if (::connect(_peer, e->ai_addr, e->ai_addrlen) == SOCKET_ERROR) {
+ err = sock_error();
+ LOG_INFO("Connect failed: %s (%d)",
+ sock_err_message(err), err);
+ closesocket(_peer);
+ _peer = -1;
+ continue;
+ }
+ LOG_INFO("Connected to %s %s", uaddr, uport);
+ break;
}
-
- LOG_INFO("Connecting %s %d", inet_ntoa(addr.sin_addr), port);
lock.unlock();
- if (::connect(_peer, (struct sockaddr *)&addr, sizeof(sockaddr_in)) == SOCKET_ERROR) {
- int err = sock_error();
- closesocket(_peer);
+ freeaddrinfo(result);
+ if (_peer == -1) {
THROW_ERR(SPICEC_ERROR_CODE_CONNECT_FAILED, "failed to connect: %s (%d)",
sock_err_message(err), err);
}
diff --git a/client/red_peer.h b/client/red_peer.h
index cb5f868..091f51a 100644
--- a/client/red_peer.h
+++ b/client/red_peer.h
@@ -113,8 +113,6 @@ public:
uint32_t recive(uint8_t* buf, uint32_t size);
uint32_t send(uint8_t* buf, uint32_t size);
- static uint32_t host_by_name(const char *host);
-
protected:
virtual void on_event() {}
virtual int get_socket() { return _peer;}