[PATCH] Re: IP_MULTICAST_IF et all / Winsock[2] value conflict
Brian Ford
Brian.Ford@flightsafety.com
Fri Sep 30 23:39:00 GMT 2005
On Fri, 30 Sep 2005, Corinna Vinschen wrote:
> On Sep 30 10:07, Brian Ford wrote:
> > We can simply translate the current constant Winsock 1 values to Winsock 2
> > ones when necessary in cygwin_[set|get]sockopt. There are only 8 values
> > that need changing, I think.
>
> Yeah, I think that we can basically do something like this. But we
> should not try to guess what the application really meant to do
> based on the incoming value and the winsock version in use.
Why not? There is no guessing involved if we do not change Cygwin's
system headers. If someone used a Windows header directly and called the
Cygwin [set|get]sockopt, well then..., that's their fault.
> Actually we have two states, applications built before we changed the
> header file and applications built after we changed the header file.
Let's just not change it ;-).
> This is visible by an internal version number maintained by Cygwin.
Ok, I'm not aware of how that works.
> The problem is that the value can be simply wrong today, because the
> application is built against the old (wrong) header file, but running
> under a Cygwin which is run-time loading Winsock2. Anyway, the idea
> to convert the incoming values based on some internal information is
> a good one.
Ok, here's an untested (as yet) patch:
2005-09-30 Brian Ford <Brian.Ford@FlightSafety.com>
* net.cc (ws2ip_optname): New function to convert IP_* socket
options from Winsock 1.1 values to Winsock 2 ones.
(cygwin_setsockopt): Use it.
(cygwin_getsockopt): Likewise.
> I want to drop Winsock1 support nevertheless. It only complicates the
> code and has no real gain.
I think I'll let you handle that one ;-).
> Yup, that's something for 1.5.20 or, more likely 1.5.21. We can discuss
> implementation details on cygwin-developers.
I was hoping this would be simple enough that it might make it in before,
but it's obviously up to you and cgf to decide.
--
Brian Ford
Senior Realtime Software Engineer
VITAL - Visual Simulation Systems
FlightSafety International
the best safety device in any aircraft is a well-trained pilot...
-------------- next part --------------
Index: net.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/net.cc,v
retrieving revision 1.194
diff -u -p -r1.194 net.cc
--- net.cc 23 Sep 2005 23:25:25 -0000 1.194
+++ net.cc 30 Sep 2005 23:35:56 -0000
@@ -663,6 +663,59 @@ cygwin_recvfrom (int fd, void *buf, int
return res;
}
+/* convert IP_* socket options from Winsock 1.1 to Winsock 2 */
+static int
+ws2ip_optname (int optname)
+{
+ /*
+ * Cygwin's system includes define the IP_* macros in terms of Winsock 1.1
+ * (Winsock.h, wsock32.lib). In Winsock 2 (Ws2tcpip.h, ws2_32.lib), some
+ * of these macros have redefined values. The 1.1 values are consistent
+ * with the original ones Steve Deering defined in "IP Multicast Extensions
+ * for 4.3BSD UNIX related systems (MULTICAST 1.2 Release)." However, these
+ * conflicted with the definitions for some IPPROTO_IP level socket options
+ * already assigned by BSD, so Berkeley changed all the values by adding 7.
+ * The Winsock 2 values are the BSD 4.4 compatible ones that we translate
+ * to here.
+ *
+ * See also: MSDN KB article Q257460
+ * http://support.microsoft.com/support/kb/articles/Q257/4/60.asp
+ *
+ * Winsock 2 defines Winsock 1.1 value
+ *
+ * #define IP_TOS 3 // 8
+ * #define IP_TTL 4 // 7
+ * #define IP_MULTICAST_IF 9 // 2
+ * #define IP_MULTICAST_TTL 10 // 3
+ * #define IP_MULTICAST_LOOP 11 // 4
+ * #define IP_ADD_MEMBERSHIP 12 // 5
+ * #define IP_DROP_MEMBERSHIP 13 // 6
+ * #define IP_DONTFRAGMENT 14 // 9
+ */
+
+ switch (optname)
+ {
+ case IP_TOS:
+ optname = 3;
+ break;
+ case IP_TTL:
+ optname = 4;
+ break;
+ case IP_MULTICAST_IF:
+ case IP_MULTICAST_TTL:
+ case IP_MULTICAST_LOOP:
+ case IP_ADD_MEMBERSHIP:
+ case IP_DROP_MEMBERSHIP:
+ optname += 7;
+ break;
+ case IP_DONTFRAGMENT:
+ optname = 14;
+ break;
+ }
+
+ return optname;
+}
+
/* exported as setsockopt: standards? */
extern "C" int
cygwin_setsockopt (int fd, int level, int optname, const void *optval,
@@ -712,7 +765,10 @@ cygwin_setsockopt (int fd, int level, in
res = -1;
else
{
- res = setsockopt (fh->get_socket (), level, optname,
+ int ws_optname = level == IPPROTO_IP && winsock2_active
+ ? ws2ip_optname (optname) : optname;
+
+ res = setsockopt (fh->get_socket (), level, ws_optname,
(const char *) optval, optlen);
if (optlen == 4)
@@ -782,7 +838,10 @@ cygwin_getsockopt (int fd, int level, in
}
else
{
- res = getsockopt (fh->get_socket (), level, optname, (char *) optval,
+ int ws_optname = level == IPPROTO_IP && winsock2_active
+ ? ws2ip_optname (optname) : optname;
+
+ res = getsockopt (fh->get_socket (), level, ws_optname, (char *) optval,
(int *) optlen);
if (optname == SO_ERROR)
More information about the Cygwin-patches
mailing list