From f4fa3a2fc017feee392c09523c307e6d25847a9b Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 15 Mar 2015 15:22:44 +0000 Subject: [PATCH] 0003 Porting pqissl to dual stack (Patch from G10H4ck) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.6-IPv6@8027 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/pqi/pqinetwork.cc | 68 +++++++------------------ libretroshare/src/pqi/pqinetwork.h | 2 +- libretroshare/src/pqi/pqissl.cc | 29 +++++++---- libretroshare/src/util/extaddrfinder.cc | 6 ++- libretroshare/src/util/rsnet.h | 1 + libretroshare/src/util/rsnet_ss.cc | 32 +++++++++--- 6 files changed, 68 insertions(+), 70 deletions(-) diff --git a/libretroshare/src/pqi/pqinetwork.cc b/libretroshare/src/pqi/pqinetwork.cc index 0ec2377c1..4c416bf97 100644 --- a/libretroshare/src/pqi/pqinetwork.cc +++ b/libretroshare/src/pqi/pqinetwork.cc @@ -870,87 +870,53 @@ int unix_socket(int domain, int type, int protocol) return osock; } - int unix_fcntl_nonblock(int fd) { - int ret; + int ret; -/******************* WINDOWS SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS // ie UNIX - ret = fcntl(fd, F_SETFL, O_NONBLOCK); - -#ifdef NET_DEBUG - std::cerr << "unix_fcntl_nonblock():" << ret << " errno:" << errno << std::endl; -#endif - -#else +#ifdef WINDOWS_SYS unsigned long int on = 1; ret = ioctlsocket(fd, FIONBIO, &on); -#ifdef NET_DEBUG - std::cerr << "unix_fcntl_nonblock()" << std::endl; -#endif if (ret != 0) { - /* store unix-style error - */ ret = -1; errno = WinToUnixError(WSAGetLastError()); } -#endif -/******************* WINDOWS SPECIFIC PART ******************/ +#else // ! WINDOWS_SYS => is UNIX ! + ret = fcntl(fd, F_SETFL, O_NONBLOCK); +#endif // WINDOWS_SYS + +#ifdef NET_DEBUG + std::cerr << "unix_fcntl_nonblock():" << ret << " errno:" << errno << std::endl; +#endif // NET_DEBUG + return ret; } - -int unix_connect(int fd, const struct sockaddr *serv_addr, socklen_t socklen) +int unix_connect(int fd, const sockaddr_storage *serv_addr) { #ifdef NET_DEBUG std::cerr << "unix_connect()"; std::cerr << std::endl; -#endif +#endif // NET_DEBUG - const struct sockaddr_storage *ss_addr = (struct sockaddr_storage *) serv_addr; - socklen_t len = socklen; - - switch (ss_addr->ss_family) - { - case AF_INET: - len = sizeof(struct sockaddr_in); - break; - case AF_INET6: - len = sizeof(struct sockaddr_in6); - break; - } - - if (len > socklen) - { - std::cerr << "unix_connect() ERROR len > socklen"; - std::cerr << std::endl; - - len = socklen; - //return EINVAL; - } - - int ret = connect(fd, serv_addr, len); - -/******************* WINDOWS SPECIFIC PART ******************/ -#ifdef WINDOWS_SYS // WINDOWS + int ret = connect(fd, (const struct sockaddr *) serv_addr, sizeof(struct sockaddr_in6)); +#ifdef WINDOWS_SYS #ifdef NET_DEBUG std::cerr << "unix_connect()" << std::endl; -#endif +#endif // NET_DEBUG if (ret != 0) { errno = WinToUnixError(WSAGetLastError()); ret = -1; } -#endif -/******************* WINDOWS SPECIFIC PART ******************/ +#endif // WINDOWS_SYS + return ret; } - int unix_getsockopt_error(int sockfd, int *err) { int ret; diff --git a/libretroshare/src/pqi/pqinetwork.h b/libretroshare/src/pqi/pqinetwork.h index 0ba8d26ca..1c4e0945a 100644 --- a/libretroshare/src/pqi/pqinetwork.h +++ b/libretroshare/src/pqi/pqinetwork.h @@ -114,7 +114,7 @@ bool LookupDNSAddr(std::string name, struct sockaddr_in &addr); int unix_close(int sockfd); int unix_socket(int domain, int type, int protocol); int unix_fcntl_nonblock(int sockfd); -int unix_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen); +int unix_connect(int sockfd, const sockaddr_storage *serv_addr); int unix_getsockopt_error(int sockfd, int *err); #ifdef WINDOWS_SYS // WINDOWS diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index f85c52611..642570e59 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -103,10 +103,10 @@ pqissl::pqissl(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm) mConnectDelay(0), mConnectTS(0), mConnectTimeout(0), mTimeoutTS(0) { - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ + RsStackMutex stack(mSslMtx); (void)stack;/**** LOCKED MUTEX ****/ /* set address to zero */ - sockaddr_storage_clear(remote_addr); + sockaddr_storage_clear(remote_addr); #ifdef PQISSL_LOG_DEBUG rslog(RSL_DEBUG_BASIC, pqisslzone, "pqissl for PeerId: " + PeerId()); @@ -632,7 +632,7 @@ int pqissl::Initiate_Connection() #endif // open socket connection to addr. - int osock = unix_socket(PF_INET, SOCK_STREAM, 0); + int osock = unix_socket(PF_INET6, SOCK_STREAM, 0); #ifdef PQISSL_LOG_DEBUG { @@ -732,10 +732,21 @@ int pqissl::Initiate_Connection() #endif #endif // WINDOWS_SYS +#ifdef IPV6_V6ONLY + int no = 0; + err = setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&no, sizeof(no)); +#ifdef PQISSL_DEBUG + if (err) std::cerr << "pqissl::Initiate_Connection: Error setting IPv6 socket dual stack" << std::endl; + else std::cerr << "pqissl::Initiate_Connection: Setting IPv6 socket dual stack" << std::endl; +#endif // PQISSL_DEBUG +#endif // IPV6_V6ONLY + mTimeoutTS = time(NULL) + mConnectTimeout; //std::cerr << "Setting Connect Timeout " << mConnectTimeout << " Seconds into Future " << std::endl; - if (0 != (err = unix_connect(osock, (struct sockaddr *) &addr, sizeof(addr)))) + sockaddr_storage_ipv4_to_ipv6(addr); + err = unix_connect(osock, &addr); + if(err) { std::string out; rs_sprintf(out, "pqissl::Initiate_Connection() connect returns:%d -> errno: %d error: %s\n", err, errno, socket_errorType(errno).c_str()); @@ -769,7 +780,7 @@ int pqissl::Initiate_Connection() } /* IF we get here ---- we Failed for some other reason. - * Should abandon this interface + * Should abandon this interface * Known reasons to get here: EINVAL (bad address) */ @@ -786,13 +797,13 @@ int pqissl::Initiate_Connection() return -1; } +#ifdef PQISSL_LOG_DEBUG else { -#ifdef PQISSL_LOG_DEBUG rslog(RSL_DEBUG_BASIC, pqisslzone, "pqissl::Init_Connection() connect returned 0"); -#endif } +#endif waiting = WAITING_SOCK_CONNECT; sockfd = osock; @@ -1223,7 +1234,7 @@ int pqissl::Extract_Failed_SSL_Certificate() RsPgpId gpgid(getX509CNString(peercert->cert_info->issuer)); std::string sslcn = getX509CNString(peercert->cert_info->subject); - AuthSSL::getAuthSSL()->FailedCertificate(peercert, gpgid,sslid,sslcn,remote_addr, false); + AuthSSL::getAuthSSL()->FailedCertificate(peercert, gpgid,sslid, sslcn, remote_addr, false); mLinkMgr->notifyDeniedConnection(gpgid, sslid, sslcn, remote_addr, false); return 1; @@ -1332,7 +1343,7 @@ int pqissl::accept(SSL *ssl, int fd, const struct sockaddr_storage &foreign_addr return accept_locked(ssl, fd, foreign_addr); } -int pqissl::accept_locked(SSL *ssl, int fd, const struct sockaddr_storage &foreign_addr) // initiate incoming connection. +int pqissl::accept_locked(SSL *ssl, int fd, const sockaddr_storage &foreign_addr) // initiate incoming connection. { if (waiting != WAITING_NOT) { diff --git a/libretroshare/src/util/extaddrfinder.cc b/libretroshare/src/util/extaddrfinder.cc index 5f15d94d9..5576336e2 100644 --- a/libretroshare/src/util/extaddrfinder.cc +++ b/libretroshare/src/util/extaddrfinder.cc @@ -81,13 +81,15 @@ static void getPage(const std::string& server_name,std::string& page) return ; } serveur.sin_addr = *(struct in_addr*) hostinfo->h_addr; - serveur.sin_port = htons(80); #ifdef EXTADDRSEARCH_DEBUG printf("Connection attempt\n"); #endif - if(unix_connect(sockfd,(struct sockaddr *)&serveur, sizeof(serveur)) == -1) + sockaddr_storage server; + sockaddr_storage_setipv4(server, &serveur); + sockaddr_storage_setport(server, 80); + if(unix_connect(sockfd, &server) == -1) { std::cerr << "ExtAddrFinder: Connection error to " << server_name << std::endl ; return ; diff --git a/libretroshare/src/util/rsnet.h b/libretroshare/src/util/rsnet.h index fa4244310..dc0b212c5 100644 --- a/libretroshare/src/util/rsnet.h +++ b/libretroshare/src/util/rsnet.h @@ -95,6 +95,7 @@ bool sockaddr_storage_setipv6(struct sockaddr_storage &addr, const sockaddr_in6 bool sockaddr_storage_ipv4_aton(struct sockaddr_storage &addr, const char *name); bool sockaddr_storage_ipv4_setport(struct sockaddr_storage &addr, const uint16_t port); +bool sockaddr_storage_ipv4_to_ipv6(sockaddr_storage &addr); // comparisons. bool operator<(const struct sockaddr_storage &a, const struct sockaddr_storage &b); diff --git a/libretroshare/src/util/rsnet_ss.cc b/libretroshare/src/util/rsnet_ss.cc index ebfa9fbe9..0db038269 100644 --- a/libretroshare/src/util/rsnet_ss.cc +++ b/libretroshare/src/util/rsnet_ss.cc @@ -220,7 +220,6 @@ bool sockaddr_storage_setport(struct sockaddr_storage &addr, uint16_t port) return false; } - bool sockaddr_storage_setipv4(struct sockaddr_storage &addr, const sockaddr_in *addr_ipv4) { #ifdef SS_DEBUG @@ -253,7 +252,6 @@ bool sockaddr_storage_setipv6(struct sockaddr_storage &addr, const sockaddr_in6 return true; } - bool sockaddr_storage_ipv4_aton(struct sockaddr_storage &addr, const char *name) { #ifdef SS_DEBUG @@ -266,6 +264,31 @@ bool sockaddr_storage_ipv4_aton(struct sockaddr_storage &addr, const char *name) return (1 == inet_aton(name, &(ipv4_ptr->sin_addr))); } +bool sockaddr_storage_ipv4_to_ipv6(sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv4_to_ipv6(sockaddr_storage &addr)" << std::endl; + + if ( addr.ss_family == AF_INET6 ) return true; + + if ( addr.ss_family == AF_INET ) + { + sockaddr_in & addr_ipv4 = (sockaddr_in &) addr; + sockaddr_in6 & addr_ipv6 = (sockaddr_in6 &) addr; + + u_int32_t ip = addr_ipv4.sin_addr.s_addr; + u_int16_t port = addr_ipv4.sin_port; + + sockaddr_storage_clear(addr); + addr_ipv6.sin6_family = AF_INET6; + addr_ipv6.sin6_port = port; + addr_ipv6.sin6_addr.s6_addr32[3] = ip; + addr_ipv6.sin6_addr.s6_addr16[5] = (u_int16_t) 0xffff; + + return true; + } + + return false; +} /******************************** Comparisions **********************************/ @@ -292,7 +315,6 @@ bool operator<(const struct sockaddr_storage &a, const struct sockaddr_storage & return false; } - bool sockaddr_storage_same(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) { #ifdef SS_DEBUG @@ -319,7 +341,6 @@ bool sockaddr_storage_same(const struct sockaddr_storage &addr, const struct soc return false; } - bool sockaddr_storage_samefamily(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) { #ifdef SS_DEBUG @@ -379,9 +400,6 @@ std::string sockaddr_storage_tostring(const struct sockaddr_storage &addr) return output; } - - - std::string sockaddr_storage_familytostring(const struct sockaddr_storage &addr) { std::string output;