]> git.saurik.com Git - wxWidgets.git/commitdiff
experimental IPv6 implementation (patch 1771429)
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 18 Nov 2007 20:53:33 +0000 (20:53 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 18 Nov 2007 20:53:33 +0000 (20:53 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50061 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

19 files changed:
configure
configure.in
docs/changes.txt
include/wx/gsocket.h
include/wx/mac/setup0.h
include/wx/motif/setup0.h
include/wx/msw/setup0.h
include/wx/msw/wince/setup.h
include/wx/msw/wrapwin.h
include/wx/os2/setup0.h
include/wx/palmos/setup0.h
include/wx/sckaddr.h
include/wx/setup_inc.h
samples/sockets/client.cpp
samples/sockets/server.cpp
setup.h.in
src/common/sckaddr.cpp
src/msw/gsocket.cpp
src/unix/gsocket.cpp

index a6872957af3bf36192be557400be65d03baadf8c..5087440286afe26c304f947dbc632655a69e0029 100755 (executable)
--- a/configure
+++ b/configure
@@ -1670,6 +1670,7 @@ Optional Features:
   --enable-http           use wxHTTP (requires wxProtocol
   --enable-fileproto      use wxFileProto class (requires wxProtocol
   --enable-sockets        use socket/network classes
+  --enable-ipv6           enable IPv6 support in wxSocket
   --enable-ole            use OLE classes (Win32 only)
   --enable-dataobj        use data object classes
   --enable-ipc            use interprocess communication (wxSocket etc.)
@@ -2934,6 +2935,7 @@ DEFAULT_wxUSE_OPENGL=no
 DEFAULT_wxUSE_ACCESSIBILITY=no
 DEFAULT_wxUSE_DATAVIEWCTRL=no
 DEFAULT_wxUSE_GRAPHICS_CONTEXT=no
+DEFAULT_wxUSE_IPV6=no
 DEFAULT_wxUSE_MEDIACTRL=no
 DEFAULT_wxUSE_TAB_DIALOG=no
 DEFAULT_wxUSE_GSTREAMER8=no
@@ -6491,6 +6493,62 @@ fi
 echo "${ECHO_T}$result" >&6; }
 
 
+          enablestring=
+          defaultval=$wxUSE_ALL_FEATURES
+          if test -z "$defaultval"; then
+              if test x"$enablestring" = xdisable; then
+                  defaultval=yes
+              else
+                  defaultval=no
+              fi
+          fi
+
+          { echo "$as_me:$LINENO: checking for --${enablestring:-enable}-ipv6" >&5
+echo $ECHO_N "checking for --${enablestring:-enable}-ipv6... $ECHO_C" >&6; }
+          # Check whether --enable-ipv6 was given.
+if test "${enable_ipv6+set}" = set; then
+  enableval=$enable_ipv6;
+                          if test "$enableval" = yes; then
+                            wx_cv_use_ipv6='wxUSE_IPV6=yes'
+                          else
+                            wx_cv_use_ipv6='wxUSE_IPV6=no'
+                          fi
+                          cache=yes
+
+else
+
+                          LINE=`grep "^wxUSE_IPV6=" ${wx_arg_cache_file}`
+                          if test "x$LINE" != x ; then
+                              eval "DEFAULT_$LINE"
+                              cache=yes
+                          else
+                              cache=no
+                          fi
+
+                          wx_cv_use_ipv6='wxUSE_IPV6=${'DEFAULT_wxUSE_IPV6":-$defaultval}"
+
+fi
+
+
+          eval "$wx_cv_use_ipv6"
+          if test "x$cache" = xyes; then
+            echo "wxUSE_IPV6=$wxUSE_IPV6" >> ${wx_arg_cache_file}.tmp
+          fi
+
+          if test x"$enablestring" = xdisable; then
+            if test $wxUSE_IPV6 = yes; then
+              result=no
+            else
+              result=yes
+            fi
+          else
+            result=$wxUSE_IPV6
+          fi
+
+          { echo "$as_me:$LINENO: result: $result" >&5
+echo "${ECHO_T}$result" >&6; }
+
+
           enablestring=
           defaultval=$wxUSE_ALL_FEATURES
           if test -z "$defaultval"; then
@@ -46982,6 +47040,78 @@ _ACEOF
 fi
 
 if test "$wxUSE_SOCKETS" = "yes" ; then
+    if test "$wxUSE_IPV6" = "yes"; then
+        { echo "$as_me:$LINENO: checking whether we have sockaddr_in6" >&5
+echo $ECHO_N "checking whether we have sockaddr_in6... $ECHO_C" >&6; }
+if test "${wx_cv_type_sockaddr_in6+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+                cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+                        #include <sys/types.h>
+                        #include <sys/socket.h>
+                        #include <netinet/in.h>
+
+int
+main ()
+{
+
+                        struct sockaddr_in6 sa6;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  wx_cv_type_sockaddr_in6=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       wx_cv_type_sockaddr_in6=no
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+fi
+{ echo "$as_me:$LINENO: result: $wx_cv_type_sockaddr_in6" >&5
+echo "${ECHO_T}$wx_cv_type_sockaddr_in6" >&6; }
+
+        if test "$wx_cv_type_sockaddr_in6"="yes"; then
+            cat >>confdefs.h <<\_ACEOF
+#define wxUSE_IPV6 1
+_ACEOF
+
+        else
+            { echo "$as_me:$LINENO: WARNING: IPv6 support not available... disabled" >&5
+echo "$as_me: WARNING: IPv6 support not available... disabled" >&2;}
+        fi
+    fi
+
     cat >>confdefs.h <<\_ACEOF
 #define wxUSE_SOCKETS 1
 _ACEOF
index b6339232907472962c04f4816adb56692dc3a1ef..0eba32eb031325f8e1cd24b94f1d805297d10181 100644 (file)
@@ -384,6 +384,7 @@ dnl features disabled by default
 DEFAULT_wxUSE_ACCESSIBILITY=no
 DEFAULT_wxUSE_DATAVIEWCTRL=no
 DEFAULT_wxUSE_GRAPHICS_CONTEXT=no
+DEFAULT_wxUSE_IPV6=no
 DEFAULT_wxUSE_MEDIACTRL=no
 DEFAULT_wxUSE_TAB_DIALOG=no
 DEFAULT_wxUSE_GSTREAMER8=no
@@ -609,6 +610,7 @@ WX_ARG_FEATURE(ftp,           [  --enable-ftp            use wxFTP (requires wxP
 WX_ARG_FEATURE(http,          [  --enable-http           use wxHTTP (requires wxProtocol], wxUSE_PROTOCOL_HTTP)
 WX_ARG_FEATURE(fileproto,     [  --enable-fileproto      use wxFileProto class (requires wxProtocol], wxUSE_PROTOCOL_FILE)
 WX_ARG_FEATURE(sockets,       [  --enable-sockets        use socket/network classes], wxUSE_SOCKETS)
+WX_ARG_FEATURE(ipv6,          [  --enable-ipv6           enable IPv6 support in wxSocket], wxUSE_IPV6)
 WX_ARG_FEATURE(ole,           [  --enable-ole            use OLE classes (Win32 only)], wxUSE_OLE)
 WX_ARG_FEATURE(dataobj,       [  --enable-dataobj        use data object classes], wxUSE_DATAOBJ)
 
@@ -6026,6 +6028,33 @@ if test "$wxUSE_SOCKETS" = "yes" ; then
 fi
 
 if test "$wxUSE_SOCKETS" = "yes" ; then
+    if test "$wxUSE_IPV6" = "yes"; then
+        AC_CACHE_CHECK(
+            [whether we have sockaddr_in6],
+            [wx_cv_type_sockaddr_in6],
+            [
+                AC_TRY_COMPILE(
+                    [
+                        #include <sys/types.h>
+                        #include <sys/socket.h>
+                        #include <netinet/in.h>
+                    ],
+                    [
+                        struct sockaddr_in6 sa6;
+                    ],
+                    wx_cv_type_sockaddr_in6=yes,
+                    wx_cv_type_sockaddr_in6=no
+                )
+            ]
+        )
+
+        if test "$wx_cv_type_sockaddr_in6"="yes"; then
+            AC_DEFINE(wxUSE_IPV6)
+        else
+            AC_MSG_WARN([IPv6 support not available... disabled])
+        fi
+    fi
+
     AC_DEFINE(wxUSE_SOCKETS)
     SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS sockets"
 fi
index 4e38803ca95747f31c33afd67254272b00d4a8d2..eaac74c1cf1c6cc18615fe369a3656303b6b2ecb 100644 (file)
@@ -160,6 +160,7 @@ Major new features in this release
 
 All:
 
+- Added (experimental) IPv6 support to wxSocket (Arcen)
 - Allow loading message catalogs from wxFileSystem (Axel Gembe)
 - Added wxMessageQueue class for inter-thread communications
 - Use UTF-8 for Unicode data in wxIPC classes (Anders Larsen)
index 46af715357b6ea5044a73b50010dcb498feb66c2..2d5b0288bb300c8984efa44b146a25a21951abbc 100644 (file)
@@ -163,7 +163,24 @@ GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname,
 unsigned long GAddress_INET_GetHostAddress(GAddress *address);
 unsigned short GAddress_INET_GetPort(GAddress *address);
 
-/* TODO: Define specific parts (INET6, UNIX) */
+#if wxUSE_IPV6
+
+GSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname);
+GSocketError GAddress_INET6_SetAnyAddress(GAddress *address);
+GSocketError GAddress_INET6_SetHostAddress(GAddress *address,
+                                          struct in6_addr hostaddr);
+GSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
+                                       const char *protocol);
+GSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port);
+
+GSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname,
+                                       size_t sbuf);
+GSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr);
+unsigned short GAddress_INET6_GetPort(GAddress *address);
+
+#endif // wxUSE_IPV6
+
+/* TODO: Define specific parts (UNIX) */
 
 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path);
 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf);
index 3212dfa83e0c82f0ae90f837eed38a65d32c2284..a617ff9a496aed361d5c093455c0f7b4e2202a32 100644 (file)
 // Unicode support
 // ----------------------------------------------------------------------------
 
-// Set wxUSE_UNICODE to 1 to compile wxWidgets in Unicode mode: wxChar will be
-// defined as wchar_t, wxString will use Unicode internally. If you set this
-// to 1, you must use wxT() macro for all literal strings in the program.
-//
-// Unicode is currently only fully supported under Windows NT/2000/XP
-// (Windows 9x doesn't support it and the programs compiled in Unicode mode
-// will not run under 9x -- but see wxUSE_UNICODE_MSLU below).
-//
-// Default is 0 (but only because of makefiles)
-//
-// Recommended setting: 1
+// These settings are obsolete: the library is always built in Unicode mode
+// now, only set wxUSE_UNICODE to 0 to compile legacy code in ANSI mode if
+// absolutely necessary -- updating it is strongly recommended as the ANSI mode
+// will disappear completely in future wxWidgets releases.
 #ifndef wxUSE_UNICODE
-    #define wxUSE_UNICODE 0
+    #define wxUSE_UNICODE 1
 #endif
 
-// Setting wxUSE_WCHAR_T to 1 gives you some degree of Unicode support without
-// compiling the program in Unicode mode. More precisely, it will be possible
-// to construct wxString from a wide (Unicode) string and convert any wxString
-// to Unicode.
-//
-// Default is 1
-//
-// Recommended setting: 1
+// wxUSE_WCHAR_T is required by wxWidgets now, don't change.
 #define wxUSE_WCHAR_T 1
 
 // ----------------------------------------------------------------------------
 // Set to 1 to use socket classes
 #define wxUSE_SOCKETS       1
 
+// Set to 1 to use ipv6 socket classes (requires wxUSE_SOCKETS)
+//
+// Notice that currently setting this option under Windows will result in
+// programs which can only run on recent OS versions (with ws2_32.dll
+// installed) which is why it is disabled by default.
+//
+// Default is 1.
+//
+// Recommended setting: 1 if you need IPv6 support
+#define wxUSE_IPV6          0
+
 // Set to 1 to enable virtual file systems (required by wxHTML)
 #define wxUSE_FILESYSTEM    1
 
index 838430120ba9ded5ff9c3b6c6fa671a07991790f..5637c68c828f878e5078dc3d595c1a53f9f861d0 100644 (file)
 // Unicode support
 // ----------------------------------------------------------------------------
 
-// Set wxUSE_UNICODE to 1 to compile wxWidgets in Unicode mode: wxChar will be
-// defined as wchar_t, wxString will use Unicode internally. If you set this
-// to 1, you must use wxT() macro for all literal strings in the program.
-//
-// Unicode is currently only fully supported under Windows NT/2000/XP
-// (Windows 9x doesn't support it and the programs compiled in Unicode mode
-// will not run under 9x -- but see wxUSE_UNICODE_MSLU below).
-//
-// Default is 0 (but only because of makefiles)
-//
-// Recommended setting: 1
+// These settings are obsolete: the library is always built in Unicode mode
+// now, only set wxUSE_UNICODE to 0 to compile legacy code in ANSI mode if
+// absolutely necessary -- updating it is strongly recommended as the ANSI mode
+// will disappear completely in future wxWidgets releases.
 #ifndef wxUSE_UNICODE
-    #define wxUSE_UNICODE 0
+    #define wxUSE_UNICODE 1
 #endif
 
-// Setting wxUSE_WCHAR_T to 1 gives you some degree of Unicode support without
-// compiling the program in Unicode mode. More precisely, it will be possible
-// to construct wxString from a wide (Unicode) string and convert any wxString
-// to Unicode.
-//
-// Default is 1
-//
-// Recommended setting: 1
+// wxUSE_WCHAR_T is required by wxWidgets now, don't change.
 #define wxUSE_WCHAR_T 1
 
 // ----------------------------------------------------------------------------
 // Set to 1 to use socket classes
 #define wxUSE_SOCKETS       1
 
+// Set to 1 to use ipv6 socket classes (requires wxUSE_SOCKETS)
+//
+// Notice that currently setting this option under Windows will result in
+// programs which can only run on recent OS versions (with ws2_32.dll
+// installed) which is why it is disabled by default.
+//
+// Default is 1.
+//
+// Recommended setting: 1 if you need IPv6 support
+#define wxUSE_IPV6          0
+
 // Set to 1 to enable virtual file systems (required by wxHTML)
 #define wxUSE_FILESYSTEM    1
 
index 2bac203e0ce601210d53c9a84b04176c53dfc5c1..58b967d0d838b53f17bd1d24473a57cab5fa6a95 100644 (file)
 // Unicode support
 // ----------------------------------------------------------------------------
 
-// Set wxUSE_UNICODE to 1 to compile wxWidgets in Unicode mode: wxChar will be
-// defined as wchar_t, wxString will use Unicode internally. If you set this
-// to 1, you must use wxT() macro for all literal strings in the program.
-//
-// Unicode is currently only fully supported under Windows NT/2000/XP
-// (Windows 9x doesn't support it and the programs compiled in Unicode mode
-// will not run under 9x -- but see wxUSE_UNICODE_MSLU below).
-//
-// Default is 0 (but only because of makefiles)
-//
-// Recommended setting: 1
+// These settings are obsolete: the library is always built in Unicode mode
+// now, only set wxUSE_UNICODE to 0 to compile legacy code in ANSI mode if
+// absolutely necessary -- updating it is strongly recommended as the ANSI mode
+// will disappear completely in future wxWidgets releases.
 #ifndef wxUSE_UNICODE
-    #define wxUSE_UNICODE 0
+    #define wxUSE_UNICODE 1
 #endif
 
-// Setting wxUSE_WCHAR_T to 1 gives you some degree of Unicode support without
-// compiling the program in Unicode mode. More precisely, it will be possible
-// to construct wxString from a wide (Unicode) string and convert any wxString
-// to Unicode.
-//
-// Default is 1
-//
-// Recommended setting: 1
+// wxUSE_WCHAR_T is required by wxWidgets now, don't change.
 #define wxUSE_WCHAR_T 1
 
 // ----------------------------------------------------------------------------
 // Set to 1 to use socket classes
 #define wxUSE_SOCKETS       1
 
+// Set to 1 to use ipv6 socket classes (requires wxUSE_SOCKETS)
+//
+// Notice that currently setting this option under Windows will result in
+// programs which can only run on recent OS versions (with ws2_32.dll
+// installed) which is why it is disabled by default.
+//
+// Default is 1.
+//
+// Recommended setting: 1 if you need IPv6 support
+#define wxUSE_IPV6          0
+
 // Set to 1 to enable virtual file systems (required by wxHTML)
 #define wxUSE_FILESYSTEM    1
 
index c2b1de3118e87f086d7992111dc02e24d927d9f5..cefc9000ace55f3db67cf6565fee94c39986621c 100644 (file)
 // Unicode support
 // ----------------------------------------------------------------------------
 
-// Set wxUSE_UNICODE to 1 to compile wxWidgets in Unicode mode: wxChar will be
-// defined as wchar_t, wxString will use Unicode internally. If you set this
-// to 1, you must use wxT() macro for all literal strings in the program.
-//
-// Unicode is currently only fully supported under Windows NT/2000/XP
-// (Windows 9x doesn't support it and the programs compiled in Unicode mode
-// will not run under 9x -- but see wxUSE_UNICODE_MSLU below).
-//
-// Default is 0 (but only because of makefiles)
-//
-// Recommended setting: 1
+// These settings are obsolete: the library is always built in Unicode mode
+// now, only set wxUSE_UNICODE to 0 to compile legacy code in ANSI mode if
+// absolutely necessary -- updating it is strongly recommended as the ANSI mode
+// will disappear completely in future wxWidgets releases.
 #ifndef wxUSE_UNICODE
-    #define wxUSE_UNICODE 0
+    #define wxUSE_UNICODE 1
 #endif
 
-// Setting wxUSE_WCHAR_T to 1 gives you some degree of Unicode support without
-// compiling the program in Unicode mode. More precisely, it will be possible
-// to construct wxString from a wide (Unicode) string and convert any wxString
-// to Unicode.
-//
-// Default is 1
-//
-// Recommended setting: 1
+// wxUSE_WCHAR_T is required by wxWidgets now, don't change.
 #define wxUSE_WCHAR_T 1
 
 // ----------------------------------------------------------------------------
 // Set to 1 to use socket classes
 #define wxUSE_SOCKETS       1
 
+// Set to 1 to use ipv6 socket classes (requires wxUSE_SOCKETS)
+//
+// Notice that currently setting this option under Windows will result in
+// programs which can only run on recent OS versions (with ws2_32.dll
+// installed) which is why it is disabled by default.
+//
+// Default is 1.
+//
+// Recommended setting: 1 if you need IPv6 support
+#define wxUSE_IPV6          0
+
 // Set to 1 to enable virtual file systems (required by wxHTML)
 #define wxUSE_FILESYSTEM    1
 
index 5f54a6f0d2dbcf1bf6f2c5a5b3548231d57d4d4d..d6bc50a870e311d10aa517a261f0cb042d78d9ed 100644 (file)
 #undef __WINDOWS__
 #endif
 
+// For IPv6 support, we must include winsock2.h before winsock.h, and
+// windows.h include winsock.h so do it before including it
+#if wxUSE_IPV6
+    #include <winsock2.h>
+#endif
+
 #include <windows.h>
 
 #if defined(__WXWINCE__) && !defined(__WINDOWS__)
@@ -106,3 +112,4 @@ WXDLLEXPORT int wxMSLU_GetSaveFileNameW(void *ofn);
 
 #endif // _WX_WRAPWIN_H_
 
+
index 5ac1e51f0d94d2290190814682a729a91793039f..7de4161ad83d87387dd3ec67475b5db2743e111c 100644 (file)
 // Unicode support
 // ----------------------------------------------------------------------------
 
-// Set wxUSE_UNICODE to 1 to compile wxWidgets in Unicode mode: wxChar will be
-// defined as wchar_t, wxString will use Unicode internally. If you set this
-// to 1, you must use wxT() macro for all literal strings in the program.
-//
-// Unicode is currently only fully supported under Windows NT/2000/XP
-// (Windows 9x doesn't support it and the programs compiled in Unicode mode
-// will not run under 9x -- but see wxUSE_UNICODE_MSLU below).
-//
-// Default is 0 (but only because of makefiles)
-//
-// Recommended setting: 1
+// These settings are obsolete: the library is always built in Unicode mode
+// now, only set wxUSE_UNICODE to 0 to compile legacy code in ANSI mode if
+// absolutely necessary -- updating it is strongly recommended as the ANSI mode
+// will disappear completely in future wxWidgets releases.
 #ifndef wxUSE_UNICODE
-    #define wxUSE_UNICODE 0
+    #define wxUSE_UNICODE 1
 #endif
 
-// Setting wxUSE_WCHAR_T to 1 gives you some degree of Unicode support without
-// compiling the program in Unicode mode. More precisely, it will be possible
-// to construct wxString from a wide (Unicode) string and convert any wxString
-// to Unicode.
-//
-// Default is 1
-//
-// Recommended setting: 1
+// wxUSE_WCHAR_T is required by wxWidgets now, don't change.
 #define wxUSE_WCHAR_T 1
 
 // ----------------------------------------------------------------------------
 // Set to 1 to use socket classes
 #define wxUSE_SOCKETS       1
 
+// Set to 1 to use ipv6 socket classes (requires wxUSE_SOCKETS)
+//
+// Notice that currently setting this option under Windows will result in
+// programs which can only run on recent OS versions (with ws2_32.dll
+// installed) which is why it is disabled by default.
+//
+// Default is 1.
+//
+// Recommended setting: 1 if you need IPv6 support
+#define wxUSE_IPV6          0
+
 // Set to 1 to enable virtual file systems (required by wxHTML)
 #define wxUSE_FILESYSTEM    1
 
index 310d413456254192a1d563e0c689b5385124194c..313ba4f3bdb2c45ffaa0592c4059eed982ec5e50 100644 (file)
 // Unicode support
 // ----------------------------------------------------------------------------
 
-// Set wxUSE_UNICODE to 1 to compile wxWidgets in Unicode mode: wxChar will be
-// defined as wchar_t, wxString will use Unicode internally. If you set this
-// to 1, you must use wxT() macro for all literal strings in the program.
-//
-// Unicode is currently only fully supported under Windows NT/2000/XP
-// (Windows 9x doesn't support it and the programs compiled in Unicode mode
-// will not run under 9x -- but see wxUSE_UNICODE_MSLU below).
-//
-// Default is 0 (but only because of makefiles)
-//
-// Recommended setting: 1
+// These settings are obsolete: the library is always built in Unicode mode
+// now, only set wxUSE_UNICODE to 0 to compile legacy code in ANSI mode if
+// absolutely necessary -- updating it is strongly recommended as the ANSI mode
+// will disappear completely in future wxWidgets releases.
 #ifndef wxUSE_UNICODE
-    #define wxUSE_UNICODE 0
+    #define wxUSE_UNICODE 1
 #endif
 
-// Setting wxUSE_WCHAR_T to 1 gives you some degree of Unicode support without
-// compiling the program in Unicode mode. More precisely, it will be possible
-// to construct wxString from a wide (Unicode) string and convert any wxString
-// to Unicode.
-//
-// Default is 1
-//
-// Recommended setting: 1
+// wxUSE_WCHAR_T is required by wxWidgets now, don't change.
 #define wxUSE_WCHAR_T 1
 
 // ----------------------------------------------------------------------------
 // Set to 1 to use socket classes
 #define wxUSE_SOCKETS       1
 
+// Set to 1 to use ipv6 socket classes (requires wxUSE_SOCKETS)
+//
+// Notice that currently setting this option under Windows will result in
+// programs which can only run on recent OS versions (with ws2_32.dll
+// installed) which is why it is disabled by default.
+//
+// Default is 1.
+//
+// Recommended setting: 1 if you need IPv6 support
+#define wxUSE_IPV6          0
+
 // Set to 1 to enable virtual file systems (required by wxHTML)
 #define wxUSE_FILESYSTEM    1
 
index f24627bd5f17c638365b5589789054e7ec6c296c..5facf0db698faba98194c2f643e2778bc8911df3 100644 (file)
@@ -121,13 +121,10 @@ private:
 
 #if wxUSE_IPV6
 
-// Experimental Only:
-//
-// IPV6 has not yet been implemented in socket layer
 class WXDLLIMPEXP_NET wxIPV6address : public wxIPaddress {
   DECLARE_DYNAMIC_CLASS(wxIPV6address)
 private:
-  struct sockaddr_in6 *m_addr;
+  wxString m_origHostname;
 public:
   wxIPV6address();
   wxIPV6address(const wxIPV6address& other);
@@ -137,7 +134,7 @@ public:
   //
   //                          hostname
   //                          3ffe:ffff:0100:f101:0210:a4ff:fee3:9566
-  // compact (base85)         Itu&-ZQ82s>J%s99FJXT
+  // compact (base85)         Itu&-ZQ82s>J%s99FJXT (depends on platform api)
   // compressed format        ::1
   // ipv4 mapped              ::ffff:1.2.3.4
   virtual bool Hostname(const wxString& name);
index 16836b44de600935edb7d9c3c16bfe813737914e..5e329cba5825732e83bc55163ad51b251cedd43a 100644 (file)
 // Set to 1 to use socket classes
 #define wxUSE_SOCKETS       1
 
+// Set to 1 to use ipv6 socket classes (requires wxUSE_SOCKETS)
+//
+// Notice that currently setting this option under Windows will result in
+// programs which can only run on recent OS versions (with ws2_32.dll
+// installed) which is why it is disabled by default.
+//
+// Default is 1.
+//
+// Recommended setting: 1 if you need IPv6 support
+#define wxUSE_IPV6          0
+
 // Set to 1 to enable virtual file systems (required by wxHTML)
 #define wxUSE_FILESYSTEM    1
 
index c7755a62b91e8e3cfb2125e4c5f11831a794e730..8c336ba34e5c507727eec9c86f91b87cbfba4b5d 100644 (file)
@@ -75,6 +75,11 @@ public:
   // event handlers for Protocols menu
   void OnTestURL(wxCommandEvent& event);
 #endif
+#if wxUSE_IPV6
+  void OnOpenConnectionIPv6(wxCommandEvent& event);
+#endif
+
+  void OpenConnection(int family = AF_INET);
 
   // event handlers for DatagramSocket menu (stub)
   void OnDatagram(wxCommandEvent& event);
@@ -110,6 +115,9 @@ enum
   CLIENT_QUIT = wxID_EXIT,
   CLIENT_ABOUT = wxID_ABOUT,
   CLIENT_OPEN = 100,
+#if wxUSE_IPV6
+  CLIENT_OPENIPV6,
+#endif
   CLIENT_TEST1,
   CLIENT_TEST2,
   CLIENT_TEST3,
@@ -131,6 +139,9 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
   EVT_MENU(CLIENT_QUIT,     MyFrame::OnQuit)
   EVT_MENU(CLIENT_ABOUT,    MyFrame::OnAbout)
   EVT_MENU(CLIENT_OPEN,     MyFrame::OnOpenConnection)
+#if wxUSE_IPV6
+  EVT_MENU(CLIENT_OPENIPV6, MyFrame::OnOpenConnectionIPv6)
+#endif
   EVT_MENU(CLIENT_TEST1,    MyFrame::OnTest1)
   EVT_MENU(CLIENT_TEST2,    MyFrame::OnTest2)
   EVT_MENU(CLIENT_TEST3,    MyFrame::OnTest3)
@@ -188,6 +199,9 @@ MyFrame::MyFrame() : wxFrame((wxFrame *)NULL, wxID_ANY,
 
   m_menuSocket = new wxMenu();
   m_menuSocket->Append(CLIENT_OPEN, _("&Open session"), _("Connect to server"));
+#if wxUSE_IPV6
+  m_menuSocket->Append(CLIENT_OPENIPV6, _("&Open session(IPv6)"), _("Connect to server(IPv6)"));
+#endif
   m_menuSocket->AppendSeparator();
   m_menuSocket->Append(CLIENT_TEST1, _("Test &1"), _("Test basic functionality"));
   m_menuSocket->Append(CLIENT_TEST2, _("Test &2"), _("Test ReadMsg and WriteMsg"));
@@ -261,9 +275,36 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
 
 void MyFrame::OnOpenConnection(wxCommandEvent& WXUNUSED(event))
 {
-  wxIPV4address addr;
+    OpenConnection(AF_INET);
+}
+#if wxUSE_IPV6
+void MyFrame::OnOpenConnectionIPv6(wxCommandEvent& WXUNUSED(event))
+{
+    OpenConnection(AF_INET6);
+}
+#endif // wxUSE_IPV6
+
+void MyFrame::OpenConnection(int family)
+{
+  wxIPaddress * addr;
+#if wxUSE_IPV6
+  wxIPV6address addr6;
+  wxIPV4address addr4;
+  if(family==AF_INET6)
+  {
+    addr = & addr6;
+  } else {
+    addr = & addr4;
+  }
+#else
+  wxIPV4address addr4;
+  addr = & addr4;
+#endif
 
   m_menuSocket->Enable(CLIENT_OPEN, false);
+#if wxUSE_IPV6
+  m_menuSocket->Enable(CLIENT_OPENIPV6, false);
+#endif
   m_menuSocket->Enable(CLIENT_CLOSE, false);
 
   // Ask user for server address
@@ -272,8 +313,8 @@ void MyFrame::OnOpenConnection(wxCommandEvent& WXUNUSED(event))
     _("Connect ..."),
     _("localhost"));
 
-  addr.Hostname(hostname);
-  addr.Service(3000);
+  addr->Hostname(hostname);
+  addr->Service(3000);
 
   // Mini-tutorial for Connect() :-)
   // ---------------------------
@@ -325,7 +366,7 @@ void MyFrame::OnOpenConnection(wxCommandEvent& WXUNUSED(event))
   // And that's all :-)
 
   m_text->AppendText(_("\nTrying to connect (timeout = 10 sec) ...\n"));
-  m_sock->Connect(addr, false);
+  m_sock->Connect(*addr, false);
   m_sock->WaitOnConnect(10);
 
   if (m_sock->IsConnected())
@@ -626,7 +667,11 @@ void MyFrame::UpdateStatusBar()
   }
   else
   {
+#if wxUSE_IPV6
+    wxIPV6address addr;
+#else
     wxIPV4address addr;
+#endif
 
     m_sock->GetPeer(addr);
     s.Printf(_("%s : %d"), (addr.Hostname()).c_str(), addr.Service());
@@ -637,6 +682,9 @@ void MyFrame::UpdateStatusBar()
 #endif // wxUSE_STATUSBAR
 
   m_menuSocket->Enable(CLIENT_OPEN, !m_sock->IsConnected() && !m_busy);
+#if wxUSE_IPV6
+  m_menuSocket->Enable(CLIENT_OPENIPV6, !m_sock->IsConnected() && !m_busy);
+#endif
   m_menuSocket->Enable(CLIENT_TEST1, m_sock->IsConnected() && !m_busy);
   m_menuSocket->Enable(CLIENT_TEST2, m_sock->IsConnected() && !m_busy);
   m_menuSocket->Enable(CLIENT_TEST3, m_sock->IsConnected() && !m_busy);
index 0e2be5b7dce110cb55169c3e68ce799dcaa09c83..452e3dcc8a5072b92623a641734568a2480a2974 100644 (file)
@@ -173,7 +173,11 @@ MyFrame::MyFrame() : wxFrame((wxFrame *)NULL, wxID_ANY,
                            wxTE_MULTILINE | wxTE_READONLY);
 
   // Create the address - defaults to localhost:0 initially
+#if wxUSE_IPV6
+  wxIPV6address addr;
+#else
   wxIPV4address addr;
+#endif
   addr.Service(3000);
 
   // Create the socket
index 2995a31037dfe55d541b7437c9eed05dac888922..585313f3e0e147e78cb440de398699eb9d81c162 100644 (file)
 
 #define wxUSE_SOCKETS       0
 
+#define wxUSE_IPV6          0
+
 #define wxUSE_FILESYSTEM    0
 
 #define wxUSE_FS_ZIP        0
index 8e79847d83e4d9ab0d9dbb778294ea45bcc15f6f..d7da5b72bc7282c6b489ca6aa175ba340e945ca6 100644 (file)
@@ -237,7 +237,7 @@ wxIPV6address::wxIPV6address()
 }
 
 wxIPV6address::wxIPV6address(const wxIPV6address& other)
-             : wxIPaddress(other)
+             : wxIPaddress(other), m_origHostname(other.m_origHostname)
 {
 }
 
@@ -252,68 +252,119 @@ bool wxIPV6address::Hostname(const wxString& name)
     wxLogWarning( _("Trying to solve a NULL hostname: giving up") );
     return false;
   }
-  return (GAddress_INET_SetHostName(m_address, name.mb_str()) == GSOCK_NOERROR);
+  m_origHostname = name;
+  return (GAddress_INET6_SetHostName(m_address, name.mb_str()) == GSOCK_NOERROR);
 }
 
-bool wxIPV6address::Hostname(unsigned char[16] WXUNUSED(addr))
+bool wxIPV6address::Hostname(unsigned char addr[16])
 {
-  return true;
+  wxString name;
+  unsigned short wk[8];
+  for ( int i = 0; i < 8; ++i )
+  {
+    wk[i] = addr[2*i];
+    wk[i] <<= 8;
+    wk[i] |= addr[2*i+1];
+  }
+  name.Printf("%x:%x:%x:%x:%x:%x:%x:%x",
+              wk[0], wk[1], wk[2], wk[3], wk[4], wk[5], wk[6], wk[7]);
+  return Hostname(name);
 }
 
 bool wxIPV6address::Service(const wxString& name)
 {
-  return (GAddress_INET_SetPortName(m_address, name.mb_str(), "tcp") == GSOCK_NOERROR);
+  return (GAddress_INET6_SetPortName(m_address, name.mb_str(), "tcp") == GSOCK_NOERROR);
 }
 
 bool wxIPV6address::Service(unsigned short port)
 {
-  return (GAddress_INET_SetPort(m_address, port) == GSOCK_NOERROR);
+  return (GAddress_INET6_SetPort(m_address, port) == GSOCK_NOERROR);
 }
 
 bool wxIPV6address::LocalHost()
 {
-  return (GAddress_INET_SetHostName(m_address, "localhost") == GSOCK_NOERROR);
+  return (GAddress_INET6_SetHostName(m_address, "localhost") == GSOCK_NOERROR);
 }
 
 bool wxIPV6address::IsLocalHost() const
 {
-  return (Hostname() == wxT("localhost") || IPAddress() == wxT("127.0.0.1"));
+  if ( Hostname() == "localhost" )
+      return true;
+
+  wxString addr = IPAddress();
+  return addr == wxT("::1") ||
+            addr == wxT("0:0:0:0:0:0:0:1") ||
+                addr == wxT("::ffff:127.0.0.1");
 }
 
 bool wxIPV6address::BroadcastAddress()
 {
-  return (GAddress_INET_SetBroadcastAddress(m_address) == GSOCK_NOERROR);
+    wxFAIL_MSG( "not implemented" );
+
+    return false;
 }
 
 bool wxIPV6address::AnyAddress()
 {
-  return (GAddress_INET_SetAnyAddress(m_address) == GSOCK_NOERROR);
+  return (GAddress_INET6_SetAnyAddress(m_address) == GSOCK_NOERROR);
 }
 
 wxString wxIPV6address::IPAddress() const
 {
-    unsigned long raw =  GAddress_INET_GetHostAddress(m_address);
-    return wxString::Format(
-        _T("%u.%u.%u.%u"),
-        (unsigned char)((raw>>24) & 0xff),
-        (unsigned char)((raw>>16) & 0xff),
-        (unsigned char)((raw>>8) & 0xff),
-        (unsigned char)(raw & 0xff)
-        );
+    unsigned char addr[16];
+    GAddress_INET6_GetHostAddress(m_address,(in6_addr*)addr);
+
+    wxUint16 words[8];
+    int i,
+        prefix_zero_count = 0;
+    for ( i = 0; i < 8; ++i )
+    {
+        words[i] = addr[i*2];
+        words[i] <<= 8;
+        words[i] |= addr[i*2+1];
+        if ( i == prefix_zero_count && words[i] == 0 )
+            ++prefix_zero_count;
+    }
+
+    wxString result;
+    if ( prefix_zero_count == 8 )
+    {
+        result = wxT( "::" );
+    }
+    else if ( prefix_zero_count == 6 && words[5] == 0xFFFF )
+    {
+        // IPv4 mapped
+        result.Printf("::ffff:%d.%d.%d.%d",
+                      addr[12], addr[13], addr[14], addr[15]);
+    }
+    else // general case
+    {
+        result = ":";
+        for ( i = prefix_zero_count; i < 8; ++i )
+        {
+            result += wxString::Format(":%x", words[i]);
+        }
+    }
+
+    return result;
 }
 
 wxString wxIPV6address::Hostname() const
 {
    char hostname[1024];
-
    hostname[0] = 0;
-   GAddress_INET_GetHostName(m_address, hostname, 1024);
+
+   if ( GAddress_INET6_GetHostName(m_address,
+                                   hostname,
+                                   WXSIZEOF(hostname)) != GSOCK_NOERROR )
+       return wxEmptyString;
+
    return wxString::FromAscii(hostname);
 }
 
 unsigned short wxIPV6address::Service() const
 {
-  return GAddress_INET_GetPort(m_address);
+  return GAddress_INET6_GetPort(m_address);
 }
 
 #endif // wxUSE_IPV6
index 393d15c29c4dd579d03917dc96d75ce6afa48e63..f71724d2649e75795fd3d95f3e3ca7c79b3cec12 100644 (file)
 #  define WX_SOCKLEN_T int
 #endif
 
+#if wxUSE_IPV6
+typedef struct sockaddr_storage wxSockAddr;
+#else
+typedef struct sockaddr wxSockAddr;
+#endif
+
+
 /* Table of GUI-related functions. We must call them indirectly because
  * of wxBase and GUI separation: */
 
@@ -181,7 +188,7 @@ GSocket::GSocket()
   m_dobind          = true;
   m_initialRecvBufferSize = -1;
   m_initialSendBufferSize = -1;
-   
+
   assert(gs_gui_functions);
   /* Per-socket GUI-specific initialization */
   m_ok = gs_gui_functions->Init_Socket(this);
@@ -301,7 +308,7 @@ GSocketError GSocket::SetPeer(GAddress *address)
 GAddress *GSocket::GetLocal()
 {
   GAddress *address;
-  struct sockaddr addr;
+  wxSockAddr addr;
   WX_SOCKLEN_T size = sizeof(addr);
   GSocketError err;
 
@@ -318,7 +325,7 @@ GAddress *GSocket::GetLocal()
     return NULL;
   }
 
-  if (getsockname(m_fd, &addr, &size) == SOCKET_ERROR)
+  if (getsockname(m_fd, (sockaddr*)&addr, &size) == SOCKET_ERROR)
   {
     m_error = GSOCK_IOERR;
     return NULL;
@@ -331,7 +338,7 @@ GAddress *GSocket::GetLocal()
      return NULL;
   }
 
-  if ((err = _GAddress_translate_from(address, &addr, size)) != GSOCK_NOERROR)
+  if ((err = _GAddress_translate_from(address, (sockaddr*)&addr, size)) != GSOCK_NOERROR)
   {
      GAddress_destroy(address);
      m_error = err;
@@ -441,7 +448,7 @@ GSocketError GSocket::SetServer()
 GSocket *GSocket::WaitConnection()
 {
   GSocket *connection;
-  struct sockaddr from;
+  wxSockAddr from;
   WX_SOCKLEN_T fromlen = sizeof(from);
   GSocketError err;
   u_long arg = 1;
@@ -475,7 +482,7 @@ GSocket *GSocket::WaitConnection()
     return NULL;
   }
 
-  connection->m_fd = accept(m_fd, &from, &fromlen);
+  connection->m_fd = accept(m_fd, (sockaddr*)&from, &fromlen);
 
   if (connection->m_fd == INVALID_SOCKET)
   {
@@ -500,7 +507,7 @@ GSocket *GSocket::WaitConnection()
     m_error = GSOCK_MEMERR;
     return NULL;
   }
-  err = _GAddress_translate_from(connection->m_peer, &from, fromlen);
+  err = _GAddress_translate_from(connection->m_peer, (sockaddr*)&from, fromlen);
   if (err != GSOCK_NOERROR)
   {
     GAddress_destroy(connection->m_peer);
@@ -1164,12 +1171,12 @@ int GSocket::Recv_Stream(char *buffer, int size)
 
 int GSocket::Recv_Dgram(char *buffer, int size)
 {
-  struct sockaddr from;
+  wxSockAddr from;
   WX_SOCKLEN_T fromlen = sizeof(from);
   int ret;
   GSocketError err;
 
-  ret = recvfrom(m_fd, buffer, size, 0, &from, &fromlen);
+  ret = recvfrom(m_fd, buffer, size, 0, (sockaddr*)&from, &fromlen);
 
   if (ret == SOCKET_ERROR)
     return SOCKET_ERROR;
@@ -1184,7 +1191,7 @@ int GSocket::Recv_Dgram(char *buffer, int size)
       return -1;
     }
   }
-  err = _GAddress_translate_from(m_peer, &from, fromlen);
+  err = _GAddress_translate_from(m_peer, (sockaddr*)&from, fromlen);
   if (err != GSOCK_NOERROR)
   {
     GAddress_destroy(m_peer);
@@ -1352,7 +1359,7 @@ GSocketError _GAddress_translate_from(GAddress *address,
     case AF_UNIX:
       address->m_family = GSOCK_UNIX;
       break;
-#ifdef AF_INET6
+#if wxUSE_IPV6
     case AF_INET6:
       address->m_family = GSOCK_INET6;
       break;
@@ -1579,6 +1586,175 @@ unsigned short GAddress_INET_GetPort(GAddress *address)
   return ntohs(addr->sin_port);
 }
 
+
+#if wxUSE_IPV6
+/*
+ * -------------------------------------------------------------------------
+ * Internet IPv6 address family
+ * -------------------------------------------------------------------------
+ */
+#include "ws2tcpip.h"
+
+#ifdef __VISUALC__
+    #pragma comment(lib,"ws2_32")
+#endif // __VISUALC__
+
+GSocketError _GAddress_Init_INET6(GAddress *address)
+{
+  struct in6_addr any_address = IN6ADDR_ANY_INIT;
+  address->m_len  = sizeof(struct sockaddr_in6);
+  address->m_addr = (struct sockaddr *) malloc(address->m_len);
+  if (address->m_addr == NULL)
+  {
+    address->m_error = GSOCK_MEMERR;
+    return GSOCK_MEMERR;
+  }
+  memset(address->m_addr,0,address->m_len);
+
+  address->m_family = GSOCK_INET6;
+  address->m_realfamily = AF_INET6;
+  ((struct sockaddr_in6 *)address->m_addr)->sin6_family = AF_INET6;
+  ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = any_address;
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname)
+{
+  assert(address != NULL);
+  CHECK_ADDRESS(address, INET6);
+
+  addrinfo hints;
+  memset( & hints, 0, sizeof( hints ) );
+  hints.ai_family = AF_INET6;
+  addrinfo * info = 0;
+  if ( getaddrinfo( hostname, "0", & hints, & info ) || ! info )
+  {
+    address->m_error = GSOCK_NOHOST;
+    return GSOCK_NOHOST;
+  }
+
+  memcpy( address->m_addr, info->ai_addr, info->ai_addrlen );
+  freeaddrinfo( info );
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET6_SetAnyAddress(GAddress *address)
+{
+  assert(address != NULL);
+
+  CHECK_ADDRESS(address, INET6);
+
+  struct in6_addr addr;
+  memset( & addr, 0, sizeof( addr ) );
+  return GAddress_INET6_SetHostAddress(address, addr);
+}
+GSocketError GAddress_INET6_SetHostAddress(GAddress *address,
+                                          struct in6_addr hostaddr)
+{
+  assert(address != NULL);
+
+  CHECK_ADDRESS(address, INET6);
+
+  ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = hostaddr;
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
+                                       const char *protocol)
+{
+  struct servent *se;
+  struct sockaddr_in6 *addr;
+
+  assert(address != NULL);
+  CHECK_ADDRESS(address, INET6);
+
+  if (!port)
+  {
+    address->m_error = GSOCK_INVPORT;
+    return GSOCK_INVPORT;
+  }
+
+  se = getservbyname(port, protocol);
+  if (!se)
+  {
+    if (isdigit(port[0]))
+    {
+      int port_int;
+
+      port_int = atoi(port);
+      addr = (struct sockaddr_in6 *)address->m_addr;
+      addr->sin6_port = htons((u_short) port_int);
+      return GSOCK_NOERROR;
+    }
+
+    address->m_error = GSOCK_INVPORT;
+    return GSOCK_INVPORT;
+  }
+
+  addr = (struct sockaddr_in6 *)address->m_addr;
+  addr->sin6_port = se->s_port;
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port)
+{
+  struct sockaddr_in6 *addr;
+
+  assert(address != NULL);
+  CHECK_ADDRESS(address, INET6);
+
+  addr = (struct sockaddr_in6 *)address->m_addr;
+  addr->sin6_port = htons(port);
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname, size_t sbuf)
+{
+  struct hostent *he;
+  char *addr_buf;
+  struct sockaddr_in6 *addr;
+
+  assert(address != NULL);
+  CHECK_ADDRESS(address, INET6);
+
+  addr = (struct sockaddr_in6 *)address->m_addr;
+  addr_buf = (char *)&(addr->sin6_addr);
+
+  he = gethostbyaddr(addr_buf, sizeof(addr->sin6_addr), AF_INET6);
+  if (he == NULL)
+  {
+    address->m_error = GSOCK_NOHOST;
+    return GSOCK_NOHOST;
+  }
+
+  strncpy(hostname, he->h_name, sbuf);
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr)
+{
+  assert(address != NULL);
+  assert(hostaddr != NULL);
+  CHECK_ADDRESS_RETVAL(address, INET6, GSOCK_INVADDR);
+  *hostaddr = ( (struct sockaddr_in6 *)address->m_addr )->sin6_addr;
+  return GSOCK_NOERROR;
+}
+
+unsigned short GAddress_INET6_GetPort(GAddress *address)
+{
+  assert(address != NULL);
+  CHECK_ADDRESS_RETVAL(address, INET6, 0);
+
+  return ntohs( ((struct sockaddr_in6 *)address->m_addr)->sin6_port );
+}
+
+#endif // wxUSE_IPV6
+
 /*
  * -------------------------------------------------------------------------
  * Unix address family
index 0fbdcb3e3571dcf848546734e00867ba21f39127..1c4e899b15e46ebf1cc3cda6cae27b52ea8ab19c 100644 (file)
@@ -450,6 +450,12 @@ struct servent *wxGetservbyname_r(const char *port, const char *protocol,
 #  define GSocket_Debug(args)
 #endif /* __GSOCKET_DEBUG__ */
 
+#if wxUSE_IPV6
+typedef struct sockaddr_storage wxSockAddr;
+#else
+typedef struct sockaddr wxSockAddr;
+#endif
+
 /* Table of GUI-related functions. We must call them indirectly because
  * of wxBase and GUI separation: */
 
@@ -678,7 +684,7 @@ GSocketError GSocket::SetPeer(GAddress *address)
 GAddress *GSocket::GetLocal()
 {
   GAddress *address;
-  struct sockaddr addr;
+  wxSockAddr addr;
   WX_SOCKLEN_T size = sizeof(addr);
   GSocketError err;
 
@@ -695,7 +701,7 @@ GAddress *GSocket::GetLocal()
     return NULL;
   }
 
-  if (getsockname(m_fd, &addr, (WX_SOCKLEN_T *) &size) < 0)
+  if (getsockname(m_fd, (sockaddr*)&addr, (WX_SOCKLEN_T *) &size) < 0)
   {
     m_error = GSOCK_IOERR;
     return NULL;
@@ -709,7 +715,7 @@ GAddress *GSocket::GetLocal()
     return NULL;
   }
 
-  err = _GAddress_translate_from(address, &addr, size);
+  err = _GAddress_translate_from(address, (sockaddr*)&addr, size);
   if (err != GSOCK_NOERROR)
   {
     GAddress_destroy(address);
@@ -827,7 +833,7 @@ GSocketError GSocket::SetServer()
  */
 GSocket *GSocket::WaitConnection()
 {
-  struct sockaddr from;
+  wxSockAddr from;
   WX_SOCKLEN_T fromlen = sizeof(from);
   GSocket *connection;
   GSocketError err;
@@ -859,7 +865,7 @@ GSocket *GSocket::WaitConnection()
     return NULL;
   }
 
-  connection->m_fd = accept(m_fd, &from, (WX_SOCKLEN_T *) &fromlen);
+  connection->m_fd = accept(m_fd, (sockaddr*)&from, (WX_SOCKLEN_T *) &fromlen);
 
   /* Reenable CONNECTION events */
   Enable(GSOCK_CONNECTION);
@@ -888,7 +894,7 @@ GSocket *GSocket::WaitConnection()
     return NULL;
   }
 
-  err = _GAddress_translate_from(connection->m_peer, &from, fromlen);
+  err = _GAddress_translate_from(connection->m_peer, (sockaddr*)&from, fromlen);
   if (err != GSOCK_NOERROR)
   {
     delete connection;
@@ -1673,7 +1679,7 @@ int GSocket::Recv_Stream(char *buffer, int size)
 
 int GSocket::Recv_Dgram(char *buffer, int size)
 {
-  struct sockaddr from;
+  wxSockAddr from;
   WX_SOCKLEN_T fromlen = sizeof(from);
   int ret;
   GSocketError err;
@@ -1682,7 +1688,7 @@ int GSocket::Recv_Dgram(char *buffer, int size)
 
   do
   {
-    ret = recvfrom(m_fd, buffer, size, 0, &from, (WX_SOCKLEN_T *) &fromlen);
+    ret = recvfrom(m_fd, buffer, size, 0, (sockaddr*)&from, (WX_SOCKLEN_T *) &fromlen);
   }
   while (ret == -1 && errno == EINTR); /* Loop until not interrupted */
 
@@ -1700,7 +1706,7 @@ int GSocket::Recv_Dgram(char *buffer, int size)
     }
   }
 
-  err = _GAddress_translate_from(m_peer, &from, fromlen);
+  err = _GAddress_translate_from(m_peer, (sockaddr*)&from, fromlen);
   if (err != GSOCK_NOERROR)
   {
     GAddress_destroy(m_peer);
@@ -1989,11 +1995,11 @@ GSocketError _GAddress_translate_from(GAddress *address,
     case AF_UNIX:
       address->m_family = GSOCK_UNIX;
       break;
-#ifdef AF_INET6
+#if wxUSE_IPV6
     case AF_INET6:
       address->m_family = GSOCK_INET6;
       break;
-#endif
+#endif // wxUSE_IPV6
     default:
     {
       address->m_error = GSOCK_INVOP;
@@ -2256,6 +2262,169 @@ unsigned short GAddress_INET_GetPort(GAddress *address)
   return ntohs(addr->sin_port);
 }
 
+#if wxUSE_IPV6
+/*
+ * -------------------------------------------------------------------------
+ * Internet IPv6 address family
+ * -------------------------------------------------------------------------
+ */
+
+GSocketError _GAddress_Init_INET6(GAddress *address)
+{
+  struct in6_addr any_address = IN6ADDR_ANY_INIT;
+  address->m_len  = sizeof(struct sockaddr_in6);
+  address->m_addr = (struct sockaddr *) malloc(address->m_len);
+  if (address->m_addr == NULL)
+  {
+    address->m_error = GSOCK_MEMERR;
+    return GSOCK_MEMERR;
+  }
+  memset(address->m_addr,0,address->m_len);
+
+  address->m_family = GSOCK_INET6;
+  address->m_realfamily = AF_INET6;
+  ((struct sockaddr_in6 *)address->m_addr)->sin6_family = AF_INET6;
+  ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = any_address;
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname)
+{
+  assert(address != NULL);
+  CHECK_ADDRESS(address, INET6);
+
+  addrinfo hints;
+  memset( & hints, 0, sizeof( hints ) );
+  hints.ai_family = AF_INET6;
+  addrinfo * info = 0;
+  if ( getaddrinfo( hostname, "0", & hints, & info ) || ! info )
+  {
+    address->m_error = GSOCK_NOHOST;
+    return GSOCK_NOHOST;
+  }
+
+  memcpy( address->m_addr, info->ai_addr, info->ai_addrlen );
+  freeaddrinfo( info );
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET6_SetAnyAddress(GAddress *address)
+{
+  assert(address != NULL);
+
+  CHECK_ADDRESS(address, INET6);
+
+  struct in6_addr addr;
+  memset( & addr, 0, sizeof( addr ) );
+  return GAddress_INET6_SetHostAddress(address, addr);
+}
+GSocketError GAddress_INET6_SetHostAddress(GAddress *address,
+                                          struct in6_addr hostaddr)
+{
+  assert(address != NULL);
+
+  CHECK_ADDRESS(address, INET6);
+
+  ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = hostaddr;
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
+                                       const char *protocol)
+{
+  struct servent *se;
+  struct sockaddr_in6 *addr;
+
+  assert(address != NULL);
+  CHECK_ADDRESS(address, INET6);
+
+  if (!port)
+  {
+    address->m_error = GSOCK_INVPORT;
+    return GSOCK_INVPORT;
+  }
+
+  se = getservbyname(port, protocol);
+  if (!se)
+  {
+    if (isdigit(port[0]))
+    {
+      int port_int;
+
+      port_int = atoi(port);
+      addr = (struct sockaddr_in6 *)address->m_addr;
+      addr->sin6_port = htons((u_short) port_int);
+      return GSOCK_NOERROR;
+    }
+
+    address->m_error = GSOCK_INVPORT;
+    return GSOCK_INVPORT;
+  }
+
+  addr = (struct sockaddr_in6 *)address->m_addr;
+  addr->sin6_port = se->s_port;
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port)
+{
+  struct sockaddr_in6 *addr;
+
+  assert(address != NULL);
+  CHECK_ADDRESS(address, INET6);
+
+  addr = (struct sockaddr_in6 *)address->m_addr;
+  addr->sin6_port = htons(port);
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname, size_t sbuf)
+{
+  struct hostent *he;
+  char *addr_buf;
+  struct sockaddr_in6 *addr;
+
+  assert(address != NULL);
+  CHECK_ADDRESS(address, INET6);
+
+  addr = (struct sockaddr_in6 *)address->m_addr;
+  addr_buf = (char *)&(addr->sin6_addr);
+
+  he = gethostbyaddr(addr_buf, sizeof(addr->sin6_addr), AF_INET6);
+  if (he == NULL)
+  {
+    address->m_error = GSOCK_NOHOST;
+    return GSOCK_NOHOST;
+  }
+
+  strncpy(hostname, he->h_name, sbuf);
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr)
+{
+  assert(address != NULL);
+  assert(hostaddr != NULL);
+  CHECK_ADDRESS_RETVAL(address, INET6, GSOCK_INVADDR);
+  *hostaddr = ( (struct sockaddr_in6 *)address->m_addr )->sin6_addr;
+  return GSOCK_NOERROR;
+}
+
+unsigned short GAddress_INET6_GetPort(GAddress *address)
+{
+  assert(address != NULL);
+  CHECK_ADDRESS_RETVAL(address, INET6, 0);
+
+  return ntohs( ((struct sockaddr_in6 *)address->m_addr)->sin6_port );
+}
+
+#endif // wxUSE_IPV6
+
 /*
  * -------------------------------------------------------------------------
  * Unix address family