summaryrefslogtreecommitdiff
path: root/ucbhelper
diff options
context:
space:
mode:
authorPascal Junck <pjunck@openoffice.org>2004-11-03 07:03:28 +0000
committerPascal Junck <pjunck@openoffice.org>2004-11-03 07:03:28 +0000
commite5a69b854d8b5f7060a0af8f2e3a38c6ccd3f00c (patch)
treef827043a983322881d3cbb1b6da83e78456ef5cf /ucbhelper
parent43c5c4945ace3252361bd5e096ecbd8115f38c66 (diff)
INTEGRATION: CWS ipv6ooo2 (1.3.90); FILE MERGED
2004/10/13 07:45:52 kso 1.3.90.2: #i33615# - Never call freeaddrinfo with a null pointer. 2004/10/11 15:45:07 kso 1.3.90.1: #i33615# - IPv6 support.
Diffstat (limited to 'ucbhelper')
-rw-r--r--ucbhelper/source/client/proxydecider.cxx205
1 files changed, 195 insertions, 10 deletions
diff --git a/ucbhelper/source/client/proxydecider.cxx b/ucbhelper/source/client/proxydecider.cxx
index 1284b4333a4d..c1ce0925cda3 100644
--- a/ucbhelper/source/client/proxydecider.cxx
+++ b/ucbhelper/source/client/proxydecider.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: proxydecider.cxx,v $
*
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
*
- * last change: $Author: vg $ $Date: 2003-07-01 14:57:56 $
+ * last change: $Author: pjunck $ $Date: 2004-11-03 08:03:28 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -63,8 +63,12 @@
TODO
**************************************************************************
+- remove resolveHostName function once OSL supports IPv6
+
*************************************************************************/
+#define OSL_DOES_NOT_SUPPORT_IPV6 1
+
#include <utility>
#include <vector>
@@ -74,9 +78,11 @@
#ifndef _RTL_REF_HXX_
#include <rtl/ref.hxx>
#endif
+#ifndef OSL_DOES_NOT_SUPPORT_IPV6
#ifndef _OSL_SOCKET_HXX_
#include <osl/socket.hxx>
#endif
+#endif
#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif
@@ -110,6 +116,124 @@ using namespace ucbhelper;
#define FTP_PROXY_NAME_KEY "ooInetFTPProxyName"
#define FTP_PROXY_PORT_KEY "ooInetFTPProxyPort"
+#ifdef OSL_DOES_NOT_SUPPORT_IPV6
+
+//=========================================================================
+
+#ifdef WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
+#include <netdb.h>
+#include <unistd.h>
+#endif
+
+namespace
+{
+
+rtl::OUString queryCanonicalHostName( const rtl::OUString & rHostName )
+{
+ rtl::OUString aResult;
+
+ struct addrinfo hints = { 0 };
+ hints.ai_socktype = SOCK_STREAM;
+
+ /*
+ AI_CANONNAME
+ If the nodename parameter is not a NULL pointer, the function searches
+ for the specified node's canonical name.
+
+ Upon successful completion, the ai_canonname member of the first
+ addrinfo structure in the linked list points to a null-terminated
+ string containing the canonical name of the specified nodename.
+
+ If the canonical name is not available or if AI_CANONNAME is not set,
+ the ai_canonname member refers to the nodename parameter or a string
+ with the same contents. The ai_flags field contents are undefined.
+ */
+ hints.ai_flags = AI_CANONNAME;
+
+ struct addrinfo * result = 0;
+
+ if ( rHostName.indexOf( ':' ) != -1 )
+ {
+#ifdef AI_NUMERICHOST /* added in the RFC2553 API */
+ hints.ai_flags |= AI_NUMERICHOST;
+#endif
+ hints.ai_family = AF_INET6;
+ }
+ else
+ {
+/* To avoid doing AAAA queries unless absolutely necessary, either use
+ * AI_ADDRCONFIG where available, or a run-time check for working IPv6
+ * support; the latter is only known to work on Linux. */
+
+#ifdef AI_ADDRCONFIG /* added in the RFC3493 API */
+ hints.ai_flags |= AI_ADDRCONFIG;
+ hints.ai_family = AF_UNSPEC;
+#else
+
+/* On Linux kernels, IPv6 is typically built as a loadable module, and
+ * socket(AF_INET6, ...) will fail if this module is not loaded, so
+ * the slow AAAA lookups can be avoided for this common case. */
+
+#ifdef LINUX
+ enum ipv6_state { unknown, disabled, enabled };
+ static ipv6_state ipv6 = unknown;
+ if ( ipv6 == unknown )
+ {
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() );
+ if ( ipv6 == unknown )
+ {
+ int fd = socket( AF_INET6, SOCK_STREAM, 0 );
+ if ( fd < 0 )
+ {
+ ipv6 = disabled;
+ }
+ else
+ {
+ ipv6 = enabled;
+ close( fd );
+ }
+ }
+ }
+
+ OSL_ENSURE( ipv6 != unknown, "ipv6 state unknown!" );
+ hints.ai_family = ( ipv6 == disabled ) ? AF_INET : AF_UNSPEC;
+#else
+ hints.ai_family = AF_UNSPEC;
+#endif /* LINUX */
+
+#endif /* AI_ADDRCONFIG */
+ }
+
+ rtl::OString aHostName(
+ rtl::OUStringToOString( rHostName, RTL_TEXTENCODING_UTF8 ) );
+ int err = getaddrinfo( aHostName.getStr(), NULL, &hints, &result );
+
+ if ( err == 0 )
+ {
+ // We're only interested in the canonical name, which is always
+ // returned in the ai_canonname field of the first addrinfo in
+ // the linked list of results.
+ aResult = rtl::OStringToOUString(
+ rtl::OString( result->ai_canonname ), RTL_TEXTENCODING_UTF8 );
+ }
+ else
+ {
+ aResult = rHostName;
+ }
+
+ if ( result != 0 )
+ freeaddrinfo( result );
+
+ return aResult;
+}
+
+} // namespace
+
+#endif /* OSL_DOES_NOT_SUPPORT_IPV6 */
+
//=========================================================================
namespace ucbhelper
{
@@ -473,7 +597,22 @@ bool InternetProxyDecider_Impl::shouldUseProxy( const rtl::OUString & rHost,
sal_Int32 nPort,
bool bUseFullyQualified ) const
{
- rtl::OUStringBuffer aBuffer( rHost );
+ rtl::OUStringBuffer aBuffer;
+
+ if ( ( rHost.indexOf( ':' ) != -1 ) &&
+ ( rHost[ 0 ] != sal_Unicode( '[' ) ) )
+ {
+ // host is given as numeric IPv6 address
+ aBuffer.appendAscii( "[" );
+ aBuffer.append( rHost );
+ aBuffer.appendAscii( "]" );
+ }
+ else
+ {
+ // host is given either as numeric IPv4 address or non-numeric hostname
+ aBuffer.append( rHost );
+ }
+
aBuffer.append( sal_Unicode( ':' ) );
aBuffer.append( rtl::OUString::valueOf( nPort ) );
const rtl::OUString aHostAndPort( aBuffer.makeStringAndClear() );
@@ -528,23 +667,41 @@ const InternetProxyServer & InternetProxyDecider_Impl::getProxy(
// Second, try match against full qualified hostname - #104401#
//////////////////////////////////////////////////////////////////
+ rtl::OUString aHost;
+
+ if ( ( rHost[ 0 ] == sal_Unicode( '[' ) ) &&
+ ( rHost.getLength() > 1 ) )
+ {
+ // host is given as numeric IPv6 address. name resolution
+ // functions need hostname without square brackets.
+ aHost = rHost.copy( 1, rHost.getLength() - 2 );
+ }
+ else
+ {
+ aHost = rHost;
+ }
+
// This might be quite expensive (DNS lookup).
- const osl::SocketAddr aAddr( rHost, nPort );
+#ifdef OSL_DOES_NOT_SUPPORT_IPV6
+ rtl::OUString aFullyQualifiedHost(
+ queryCanonicalHostName( aHost ).toAsciiLowerCase() );
+#else
+ const osl::SocketAddr aAddr( aHost, nPort );
rtl::OUString aFullyQualifiedHost(
aAddr.getHostname().toAsciiLowerCase() );
-
+#endif
// Error resolving name? -> fallback.
if ( !aFullyQualifiedHost.getLength() )
- aFullyQualifiedHost = rHost;
+ aFullyQualifiedHost = aHost;
- if ( aFullyQualifiedHost != rHost )
+ if ( aFullyQualifiedHost != aHost )
{
if ( !shouldUseProxy( aFullyQualifiedHost, nPort, false ) )
return m_aEmptyProxy;
}
//////////////////////////////////////////////////////////////////
- // Third, try match of fully qualified entries in no-proxy lit
+ // Third, try match of fully qualified entries in no-proxy list
// against full qualified hostname
//
// Example:
@@ -704,7 +861,16 @@ void InternetProxyDecider_Impl::setNoProxyList(
{
rtl::OUString aServer;
rtl::OUString aPort;
- sal_Int32 nColonPos = aToken.indexOf( ':' );
+
+ // numerical IPv6 address?
+ bool bIPv6Address = false;
+ sal_Int32 nClosedBracketPos = aToken.indexOf( ']' );
+ if ( nClosedBracketPos == -1 )
+ nClosedBracketPos = 0;
+ else
+ bIPv6Address = true;
+
+ sal_Int32 nColonPos = aToken.indexOf( ':', nClosedBracketPos );
if ( nColonPos == -1 )
{
// No port given, server pattern equals current token
@@ -736,12 +902,31 @@ void InternetProxyDecider_Impl::setNoProxyList(
// entry specifies exactly one non-fully qualified server
// name.
+ // remove square brackets from host name in case it's
+ // a numerical IPv6 address.
+ if ( bIPv6Address )
+ aServer = aServer.copy( 1, aServer.getLength() - 2 );
+
// This might be quite expensive (DNS lookup).
+#ifdef OSL_DOES_NOT_SUPPORT_IPV6
+ rtl::OUString aTmp
+ = queryCanonicalHostName( aServer ).toAsciiLowerCase();
+#else
const osl::SocketAddr aAddr( aServer, 0 );
rtl::OUString aTmp = aAddr.getHostname().toAsciiLowerCase();
+#endif
if ( aTmp != aServer.toAsciiLowerCase() )
{
- aFullyQualifiedHost.append( aTmp );
+ if ( bIPv6Address )
+ {
+ aFullyQualifiedHost.appendAscii( "[" );
+ aFullyQualifiedHost.append( aTmp );
+ aFullyQualifiedHost.appendAscii( "]" );
+ }
+ else
+ {
+ aFullyQualifiedHost.append( aTmp );
+ }
aFullyQualifiedHost.appendAscii( ":" );
aFullyQualifiedHost.append( aPort );
}