Hannes Lerchl
2010-04-14 16:43:52 UTC
Hello,
we're developing a testing application using omniORB (to be accessible via Corba). The application is meant to be run on MS Windows so I've downloaded the binary package omniORB-4.1.3-x86_win32-vs9.zip
Things work OK but one of our customers "discovered" a strange "feature" of windows' socket library which is used by omniORB:
Windows has a fundamentally different understanding of the socket option SO_REUSEADDR than posix systems:
Instead of immediately reusing the port after program termination the socket is free for reuse even if another program is still using it. The outcome is undefined and most probably both applications are unhappy (for our application this meant that further communication was impossible without any of the two applications knowing what went wrong).
See also http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4476378 and http://msdn.microsoft.com/en-us/library/ms740621%28VS.85%29.aspx
I didn't find out whether SO_REUSEADDR and SO_EXCLUSIVEADDRUSE (which is Microsofts' way of fixing the described issue) can be used together but using only SO_REUSEADDR on windows does more harm than good.
So I patched the two files src/lib/omniORB/orbcore/ssl/sslEndpoint.cc and src/lib/omniORB/orbcore/tcp/tcpEndpoint.cc (where SO_REUSEADDR is set) and replaced it with SO_EXCLUSIVEADDRUSE. The patch is not perfect but it works for us and now the second started instance of our application gets a socket error when booting (as desired).
Below I append the patch we applied (created with mercurial but it should be compatible with standard unix patch)
Best regards,
Hannes Lerchl
diff -r d5da39bdabf5 -r cd803700f307 src/lib/omniORB/orbcore/ssl/sslEndpoint.cc
--- a/src/lib/omniORB/orbcore/ssl/sslEndpoint.cc Wed Apr 07 10:50:27 2010 +0200
+++ b/src/lib/omniORB/orbcore/ssl/sslEndpoint.cc Fri Apr 09 10:10:46 2010 +0200
@@ -482,11 +482,23 @@
if (pd_address.port) {
int valtrue = 1;
+#ifdef __WIN32__
+ // Windows has a fundamentally different understanding about SO_REUSEADDR
+ // so we don't use it but take SO_EXCLUSIVEADDRUSE. See also
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4476378 and
+ // http://msdn.microsoft.com/en-us/library/ms740621%28VS.85%29.aspx
+ if (setsockopt(pd_socket,SOL_SOCKET,SO_EXCLUSIVEADDRUSE,
+ (char*)&valtrue,sizeof(int)) == RC_SOCKET_ERROR) {
+
+ omniORB::logs(2, "Warning: failed to set SO_EXCLUSIVEADDRUSE option.");
+ }
+#else
if (setsockopt(pd_socket,SOL_SOCKET,SO_REUSEADDR,
(char*)&valtrue,sizeof(int)) == RC_SOCKET_ERROR) {
omniORB::logs(2, "Warning: failed to set SO_REUSEADDR option.");
}
+#endif
}
if (omniORB::trace(25)) {
omniORB::logger log;
diff -r d5da39bdabf5 -r cd803700f307 src/lib/omniORB/orbcore/tcp/tcpEndpoint.cc
--- a/src/lib/omniORB/orbcore/tcp/tcpEndpoint.cc Wed Apr 07 10:50:27 2010 +0200
+++ b/src/lib/omniORB/orbcore/tcp/tcpEndpoint.cc Fri Apr 09 10:10:46 2010 +0200
@@ -470,11 +470,23 @@
if (pd_address.port) {
int valtrue = 1;
+#ifdef __WIN32__
+ // Windows has a fundamentally different understanding about SO_REUSEADDR
+ // so we don't use it but take SO_EXCLUSIVEADDRUSE. See also
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4476378 and
+ // http://msdn.microsoft.com/en-us/library/ms740621%28VS.85%29.aspx
+ if (setsockopt(pd_socket,SOL_SOCKET,SO_EXCLUSIVEADDRUSE,
+ (char*)&valtrue,sizeof(int)) == RC_SOCKET_ERROR) {
+
+ omniORB::logs(2, "Warning: failed to set SO_EXCLUSIVEADDRUSE option.");
+ }
+#else
if (setsockopt(pd_socket,SOL_SOCKET,SO_REUSEADDR,
(char*)&valtrue,sizeof(int)) == RC_SOCKET_ERROR) {
omniORB::logs(2, "Warning: failed to set SO_REUSEADDR option.");
}
+#endif
}
if (omniORB::trace(25)) {
omniORB::logger log;
--
Dipl.-Inf. Hannes Lerchl, Senior Software Architect
Phone: +49.89.45 23 47-22
--
jambit Software Development & Management GmbH
Nymphenburger Stra?e 13-15, D-80335 M?nchen
Phone: +49.89.45 23 47-0 Fax: +49.89.45 23 47-70
http://www.jambit.com where innovation works
Gesch?ftsf?hrer: Peter F. Fellinger, Markus Hartinger
Sitz: M?nchen; Registergericht: M?nchen, HRB 129139
we're developing a testing application using omniORB (to be accessible via Corba). The application is meant to be run on MS Windows so I've downloaded the binary package omniORB-4.1.3-x86_win32-vs9.zip
Things work OK but one of our customers "discovered" a strange "feature" of windows' socket library which is used by omniORB:
Windows has a fundamentally different understanding of the socket option SO_REUSEADDR than posix systems:
Instead of immediately reusing the port after program termination the socket is free for reuse even if another program is still using it. The outcome is undefined and most probably both applications are unhappy (for our application this meant that further communication was impossible without any of the two applications knowing what went wrong).
See also http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4476378 and http://msdn.microsoft.com/en-us/library/ms740621%28VS.85%29.aspx
I didn't find out whether SO_REUSEADDR and SO_EXCLUSIVEADDRUSE (which is Microsofts' way of fixing the described issue) can be used together but using only SO_REUSEADDR on windows does more harm than good.
So I patched the two files src/lib/omniORB/orbcore/ssl/sslEndpoint.cc and src/lib/omniORB/orbcore/tcp/tcpEndpoint.cc (where SO_REUSEADDR is set) and replaced it with SO_EXCLUSIVEADDRUSE. The patch is not perfect but it works for us and now the second started instance of our application gets a socket error when booting (as desired).
Below I append the patch we applied (created with mercurial but it should be compatible with standard unix patch)
Best regards,
Hannes Lerchl
diff -r d5da39bdabf5 -r cd803700f307 src/lib/omniORB/orbcore/ssl/sslEndpoint.cc
--- a/src/lib/omniORB/orbcore/ssl/sslEndpoint.cc Wed Apr 07 10:50:27 2010 +0200
+++ b/src/lib/omniORB/orbcore/ssl/sslEndpoint.cc Fri Apr 09 10:10:46 2010 +0200
@@ -482,11 +482,23 @@
if (pd_address.port) {
int valtrue = 1;
+#ifdef __WIN32__
+ // Windows has a fundamentally different understanding about SO_REUSEADDR
+ // so we don't use it but take SO_EXCLUSIVEADDRUSE. See also
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4476378 and
+ // http://msdn.microsoft.com/en-us/library/ms740621%28VS.85%29.aspx
+ if (setsockopt(pd_socket,SOL_SOCKET,SO_EXCLUSIVEADDRUSE,
+ (char*)&valtrue,sizeof(int)) == RC_SOCKET_ERROR) {
+
+ omniORB::logs(2, "Warning: failed to set SO_EXCLUSIVEADDRUSE option.");
+ }
+#else
if (setsockopt(pd_socket,SOL_SOCKET,SO_REUSEADDR,
(char*)&valtrue,sizeof(int)) == RC_SOCKET_ERROR) {
omniORB::logs(2, "Warning: failed to set SO_REUSEADDR option.");
}
+#endif
}
if (omniORB::trace(25)) {
omniORB::logger log;
diff -r d5da39bdabf5 -r cd803700f307 src/lib/omniORB/orbcore/tcp/tcpEndpoint.cc
--- a/src/lib/omniORB/orbcore/tcp/tcpEndpoint.cc Wed Apr 07 10:50:27 2010 +0200
+++ b/src/lib/omniORB/orbcore/tcp/tcpEndpoint.cc Fri Apr 09 10:10:46 2010 +0200
@@ -470,11 +470,23 @@
if (pd_address.port) {
int valtrue = 1;
+#ifdef __WIN32__
+ // Windows has a fundamentally different understanding about SO_REUSEADDR
+ // so we don't use it but take SO_EXCLUSIVEADDRUSE. See also
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4476378 and
+ // http://msdn.microsoft.com/en-us/library/ms740621%28VS.85%29.aspx
+ if (setsockopt(pd_socket,SOL_SOCKET,SO_EXCLUSIVEADDRUSE,
+ (char*)&valtrue,sizeof(int)) == RC_SOCKET_ERROR) {
+
+ omniORB::logs(2, "Warning: failed to set SO_EXCLUSIVEADDRUSE option.");
+ }
+#else
if (setsockopt(pd_socket,SOL_SOCKET,SO_REUSEADDR,
(char*)&valtrue,sizeof(int)) == RC_SOCKET_ERROR) {
omniORB::logs(2, "Warning: failed to set SO_REUSEADDR option.");
}
+#endif
}
if (omniORB::trace(25)) {
omniORB::logger log;
--
Dipl.-Inf. Hannes Lerchl, Senior Software Architect
Phone: +49.89.45 23 47-22
--
jambit Software Development & Management GmbH
Nymphenburger Stra?e 13-15, D-80335 M?nchen
Phone: +49.89.45 23 47-0 Fax: +49.89.45 23 47-70
http://www.jambit.com where innovation works
Gesch?ftsf?hrer: Peter F. Fellinger, Markus Hartinger
Sitz: M?nchen; Registergericht: M?nchen, HRB 129139