diff --git a/configure b/configure index a6872957af..5087440286 100755 --- 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 + #include + #include + +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 diff --git a/configure.in b/configure.in index b633923290..0eba32eb03 100644 --- a/configure.in +++ b/configure.in @@ -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 + #include + #include + ], + [ + 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 diff --git a/docs/changes.txt b/docs/changes.txt index 4e38803ca9..eaac74c1cf 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -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) diff --git a/include/wx/gsocket.h b/include/wx/gsocket.h index 46af715357..2d5b0288bb 100644 --- a/include/wx/gsocket.h +++ b/include/wx/gsocket.h @@ -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); diff --git a/include/wx/mac/setup0.h b/include/wx/mac/setup0.h index 3212dfa83e..a617ff9a49 100644 --- a/include/wx/mac/setup0.h +++ b/include/wx/mac/setup0.h @@ -148,29 +148,15 @@ // 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 // ---------------------------------------------------------------------------- @@ -455,6 +441,17 @@ // 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 diff --git a/include/wx/motif/setup0.h b/include/wx/motif/setup0.h index 838430120b..5637c68c82 100644 --- a/include/wx/motif/setup0.h +++ b/include/wx/motif/setup0.h @@ -147,29 +147,15 @@ // 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 // ---------------------------------------------------------------------------- @@ -454,6 +440,17 @@ // 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 diff --git a/include/wx/msw/setup0.h b/include/wx/msw/setup0.h index 2bac203e0c..58b967d0d8 100644 --- a/include/wx/msw/setup0.h +++ b/include/wx/msw/setup0.h @@ -147,29 +147,15 @@ // 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 // ---------------------------------------------------------------------------- @@ -454,6 +440,17 @@ // 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 diff --git a/include/wx/msw/wince/setup.h b/include/wx/msw/wince/setup.h index c2b1de3118..cefc9000ac 100644 --- a/include/wx/msw/wince/setup.h +++ b/include/wx/msw/wince/setup.h @@ -147,29 +147,15 @@ // 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 // ---------------------------------------------------------------------------- @@ -454,6 +440,17 @@ // 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 diff --git a/include/wx/msw/wrapwin.h b/include/wx/msw/wrapwin.h index 5f54a6f0d2..d6bc50a870 100644 --- a/include/wx/msw/wrapwin.h +++ b/include/wx/msw/wrapwin.h @@ -57,6 +57,12 @@ #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 +#endif + #include #if defined(__WXWINCE__) && !defined(__WINDOWS__) @@ -106,3 +112,4 @@ WXDLLEXPORT int wxMSLU_GetSaveFileNameW(void *ofn); #endif // _WX_WRAPWIN_H_ + diff --git a/include/wx/os2/setup0.h b/include/wx/os2/setup0.h index 5ac1e51f0d..7de4161ad8 100644 --- a/include/wx/os2/setup0.h +++ b/include/wx/os2/setup0.h @@ -147,29 +147,15 @@ // 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 // ---------------------------------------------------------------------------- @@ -454,6 +440,17 @@ // 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 diff --git a/include/wx/palmos/setup0.h b/include/wx/palmos/setup0.h index 310d413456..313ba4f3bd 100644 --- a/include/wx/palmos/setup0.h +++ b/include/wx/palmos/setup0.h @@ -147,29 +147,15 @@ // 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 // ---------------------------------------------------------------------------- @@ -454,6 +440,17 @@ // 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 diff --git a/include/wx/sckaddr.h b/include/wx/sckaddr.h index f24627bd5f..5facf0db69 100644 --- a/include/wx/sckaddr.h +++ b/include/wx/sckaddr.h @@ -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); diff --git a/include/wx/setup_inc.h b/include/wx/setup_inc.h index 16836b44de..5e329cba58 100644 --- a/include/wx/setup_inc.h +++ b/include/wx/setup_inc.h @@ -436,6 +436,17 @@ // 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 diff --git a/samples/sockets/client.cpp b/samples/sockets/client.cpp index c7755a62b9..8c336ba34e 100644 --- a/samples/sockets/client.cpp +++ b/samples/sockets/client.cpp @@ -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); diff --git a/samples/sockets/server.cpp b/samples/sockets/server.cpp index 0e2be5b7dc..452e3dcc8a 100644 --- a/samples/sockets/server.cpp +++ b/samples/sockets/server.cpp @@ -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 diff --git a/setup.h.in b/setup.h.in index 2995a31037..585313f3e0 100644 --- a/setup.h.in +++ b/setup.h.in @@ -247,6 +247,8 @@ #define wxUSE_SOCKETS 0 +#define wxUSE_IPV6 0 + #define wxUSE_FILESYSTEM 0 #define wxUSE_FS_ZIP 0 diff --git a/src/common/sckaddr.cpp b/src/common/sckaddr.cpp index 8e79847d83..d7da5b72bc 100644 --- a/src/common/sckaddr.cpp +++ b/src/common/sckaddr.cpp @@ -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 diff --git a/src/msw/gsocket.cpp b/src/msw/gsocket.cpp index 393d15c29c..f71724d264 100644 --- a/src/msw/gsocket.cpp +++ b/src/msw/gsocket.cpp @@ -88,6 +88,13 @@ # 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 diff --git a/src/unix/gsocket.cpp b/src/unix/gsocket.cpp index 0fbdcb3e35..1c4e899b15 100644 --- a/src/unix/gsocket.cpp +++ b/src/unix/gsocket.cpp @@ -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