pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


Windows |bindresvport_()| prototype
Posted by Anonymous on Tue 26th Mar 2024 15:18
raw | new post
modification of post by Anonymous (view diff)

  1. diff --git a/cygwin/README.bintarball.txt b/cygwin/README.bintarball.txt
  2. index b1b66e0..9fa5222 100644
  3. --- a/cygwin/README.bintarball.txt
  4. +++ b/cygwin/README.bintarball.txt
  5. @@ -129,10 +129,6 @@ $ (set -o xtrace ; cd / && tar -tf ~/download/${bintarball.base_filename}.tar.bz
  6.  $ /sbin/msnfs41client run_daemon
  7.  
  8.  # Mount a filesystem and use it
  9. -# - requires that NFSv4 server accepts connections from a TCP port
  10. -# number > 1024, which can be archived on Linux with the "insecure"
  11. -# export option in /etc/exports, or "resvport" on Solaris/Illumos
  12. -# (see nfs(5))
  13.  $ /sbin/nfs_mount -o rw N 10.49.20.110:/net_tmpfs2
  14.  Successfully mounted '10.49.20.110@2049' to drive 'N:'
  15.  $ cd /cygdrive/n/
  16. @@ -230,15 +226,15 @@ $ /sbin/nfs_mount
  17.    A::EVERYONE@:rtcy
  18.    ---- snip ----
  19.  
  20. -- nfs_mount only works when the NFSv4 server allows connections from
  21. -  ports >= 1024, as Windows does not allow the Windows NFSv4 client
  22. -  to use a "privileged port" (i.e. TCP port number < 1024)).
  23. +- nfs_mount.exe vs. reserved ports:
  24.    By default the NFSv4 server on Solaris, Illumos, Linux
  25.    etc. only accepts connections if the NFSv4 client uses a
  26. -  "privileged (TCP) port", i.e. a port number < 1024.
  27. -  This can be worked around by using the "insecure" export option in
  28. -  Linux /etc/exports, which allows connections from ports >= 1024,
  29. -  and for Solaris/Illumos see nfs(5), option "resvport".
  30. +  "privileged (TCP) port", i.e. using a TCP port number < 1024.
  31. +  If nfsd.exe/nfsd_debug.exe is started without the Windows priviledge
  32. +  to use reserved ports, then a mount attempt can fail.
  33. +  This can be worked around on the NFSv4 server side - on Linux using
  34. +  the "insecure" export option in  /etc/exports and on Solaris/Illumos
  35. +  using export option "resvport" (see nfs(5)).
  36.  
  37.  
  38.  #
  39. diff --git a/libtirpc/src/bindresvport.c b/libtirpc/src/bindresvport.c
  40. index 01d1921..be56a6c 100644
  41. --- a/libtirpc/src/bindresvport.c
  42. +++ b/libtirpc/src/bindresvport.c
  43. @@ -1,5 +1,6 @@
  44.  /*
  45.   * Copyright (c) 2009, Sun Microsystems, Inc.
  46. + * Copyright (c) 2024, Roland Mainz <roland.mainz@nrubsig.org>
  47.   * All rights reserved.
  48.   *
  49.   * Redistribution and use in source and binary forms, with or without
  50. @@ -32,20 +33,30 @@
  51.   * Copyright (c) 1987 by Sun Microsystems, Inc.
  52.   *
  53.   * Portions Copyright(C) 1996, Jason Downs.  All rights reserved.
  54. + * Portions Copyright(C) 2024, Roland Mainz <roland.mainz@nrubsig.org>
  55.   */
  56.  
  57.  #include <wintirpc.h>
  58.  #include <sys/types.h>
  59. -//#include <sys/socket.h>
  60. -
  61. -//#include <netinet/in.h>
  62. +#ifndef _WIN32
  63. +#include <sys/socket.h>
  64. +#include <netinet/in.h>
  65. +#endif
  66.  
  67.  #include <errno.h>
  68.  #include <string.h>
  69. -//#include <unistd.h>
  70. +#ifndef _WIN32
  71. +#include <unistd.h>
  72. +#endif
  73.  
  74.  #include <rpc/rpc.h>
  75.  
  76. +#ifdef _WIN32
  77. +#include <winsock2.h>
  78. +#include <mstcpip.h>
  79. +#include <ws2ipdef.h>
  80. +#endif
  81. +
  82.  /*
  83.   * Bind a socket to a privileged IP port
  84.   */
  85. @@ -139,18 +150,147 @@ bindresvport_sa(sd, sa)
  86.          return (res);
  87.  }
  88.  
  89. +#elif defined(_WIN32)
  90. +
  91. +#define STARTPORT 600
  92. +#define ENDPORT (IPPORT_RESERVED - 1)
  93. +#define NPORTS  (ENDPORT - STARTPORT + 1)
  94. +
  95. +/* Debug */
  96. +#if 0
  97. +#define BRP_D(x) x
  98.  #else
  99. -/*----------------------
  100. -#if defined(_WIN32)
  101. +#define BRP_D(x)
  102. +#endif
  103. +
  104. +/* fixme: not threadsafe, we should use |portnum_lock| */
  105. +static int bindresvport_sa_last_n = 0;
  106.  
  107.  int
  108.  bindresvport_sa(int sd, struct sockaddr *sa)
  109.  {
  110. -       fprintf(stderr, "Do-nothing bindresvport_sa!\n");
  111. -       return 0;
  112. +       int res = 1;
  113. +       int ioctlres;
  114. +       int lasterr;
  115. +       SOCKET sd_sock;
  116. +       int currport;
  117. +       int n;
  118. +
  119. +       INET_PORT_RANGE portRange;
  120. +       INET_PORT_RESERVATION_INSTANCE portRes;
  121. +       DWORD bytesReturned;
  122. +
  123. +       BRP_D((void)fprintf(stdout,
  124. +               "--> bindresvport_sa(sd=%d,sa=0x%p): "
  125. +               "bindresvport_sa_last_n=%d\n",
  126. +               sd, sa, bindresvport_sa_last_n));
  127. +
  128. +       sd_sock = _get_osfhandle(sd);
  129. +
  130. +       for (n = 0 ; n < NPORTS ; n++) {
  131. +               currport = ((n+bindresvport_sa_last_n)%NPORTS)+STARTPORT;
  132. +
  133. +               portRange.StartPort = htons(currport);
  134. +               portRange.NumberOfPorts = 1;
  135. +
  136. +               (void)memset(&portRes, 0, sizeof(portRes));
  137. +               bytesReturned = 0;
  138. +
  139. +               BRP_D((void)fprintf(stdout,
  140. +                       "bindresvport_sa(sd=%d,sa=0x%p): "
  141. +                       "trying n=%d, bindresvport_sa_last_n=%d, port=%d ...\n",
  142. +                       sd, sa, n, bindresvport_sa_last_n,
  143. +                       (int)ntohs(portRange.StartPort)));
  144. +               ioctlres = WSAIoctl(sd_sock,
  145. +                       SIO_ACQUIRE_PORT_RESERVATION,
  146. +                       (LPVOID)&portRange,
  147. +                       sizeof(INET_PORT_RANGE),
  148. +                       (LPVOID)&portRes,
  149. +                       sizeof(INET_PORT_RESERVATION_INSTANCE),
  150. +                       &bytesReturned, NULL, NULL);
  151. +               lasterr = WSAGetLastError();
  152. +
  153. +               if ((ioctlres != 0) && (lasterr == WSAEADDRINUSE)) {
  154. +                       BRP_D((void)fprintf(stderr,
  155. +                               "bindresvport_sa(sd=%d,sa=0x%p): "
  156. +                               "port=%d in use, trying next port...\n",
  157. +                               sd, sa, currport));
  158. +                       continue;
  159. +               }
  160. +
  161. +               if (ioctlres != 0) {
  162. +                       warnx("bindresvport_sa(sd=%d,sa=0x%p): "
  163. +                               "SIO_ACQUIRE_PORT_RESERVATION failed "
  164. +                               "with error = %d\n",
  165. +                               sd, sa, lasterr);
  166. +                       res = 1;
  167. +                       bindresvport_sa_last_n = n+1;
  168. +                       goto out;
  169. +               }
  170. +
  171. +               /* Success */
  172. +               bindresvport_sa_last_n = n+1;
  173. +               break;
  174. +       }
  175. +
  176. +       if (n == NPORTS) {
  177. +               warnx("bindresvport_sa(sd=%d,sa=0x%p): "
  178. +                       "n(=%d) == NPORTS(=%d), "
  179. +                       "no reserved port available\n", n, NPORTS);
  180. +               res = 1;
  181. +               goto out;
  182. +       }
  183. +
  184. +       BRP_D((void)fprintf(stdout, "bindresvport_sa(sd=%d,sa=0x%p): "
  185. +               "SIO_ACQUIRE_PORT_RESERVATION succeeded, "
  186. +               "bytesReturned = %u, StartPort=%d, NumberOfPorts=%d, "
  187. +               "Token=0x%llx\n",
  188. +               sd, sa, bytesReturned, (int)ntohs(portRes.StartPort),
  189. +               portRes.NumberOfPorts, (long long)portRes.Token));
  190. +
  191. +       bytesReturned = 0;
  192. +       ioctlres = WSAIoctl(sd_sock, SIO_ASSOCIATE_PORT_RESERVATION,
  193. +               (LPVOID)&portRes.Token, sizeof(ULONG64), NULL, 0,
  194. +               &bytesReturned, NULL, NULL);
  195. +       lasterr = WSAGetLastError();
  196. +       if (ioctlres != 0) {
  197. +               warnx("bindresvport_sa(sd=%d,sa=0x%p): "
  198. +                       "WSAIoctl(SIO_ASSOCIATE_PORT_RESERVATION) "
  199. +                       "failed with error = %d\n",
  200. +                       sd, sa, lasterr);
  201. +               res = 1;
  202. +               goto out;
  203. +       }
  204. +
  205. +       BRP_D((void)fprintf(stdout, "bindresvport_sa(sd=%d,sa=0x%p): "
  206. +               "WSAIoctl(SIO_ASSOCIATE_PORT_RESERVATION) succeeded, "
  207. +               "bytesReturned = %u\n",
  208. +               sd, sa, bytesReturned));
  209. +       res = 0;
  210. +
  211. +       /*
  212. +        * FIXME: We should call |SIO_RELEASE_PORT_RESERVATION|,
  213. +        * but we cannot do that while |sd| is open and using the
  214. +        * reservation.
  215. +        * So basically we to store the token, and then use a second
  216. +        * socket, with matching protocol&co attributes, just to
  217. +        * release the reservation.
  218. +        *
  219. +        * A possible solution might be to derive a "control socket"
  220. +        * from |sd|, and do the reservation ioctl using that socket.
  221. +        *
  222. +        * For now we ignore this, and assume noone will do more
  223. +        * than |NPORTS| { mount, umount }-sequences during
  224. +        * nfsd.exe/nfsd_debug.exe lifetime
  225. +        */
  226. +out:
  227. +       BRP_D((void)fprintf(stdout,
  228. +               "<-- bindresvport_sa(sd=%d,sa=0x%p) returning res=%d\n",
  229. +               sd, sa, res));
  230. +       return res;
  231.  }
  232.  #else
  233. --------------------------*/
  234. +
  235.  #define IP_PORTRANGE 19
  236.  #define IP_PORTRANGE_LOW 2
  237.  
  238. @@ -174,29 +314,16 @@ bindresvport_sa(sd, sa)
  239.         int proto, portrange, portlow;
  240.         u_int16_t *portp;
  241.         socklen_t salen;
  242. -#ifdef _WIN32
  243. -               WSAPROTOCOL_INFO proto_info;
  244. -               int proto_info_size = sizeof(proto_info);
  245. -#endif
  246.  
  247.         if (sa == NULL) {
  248.                 salen = sizeof(myaddr);
  249.                 sa = (struct sockaddr *)&myaddr;
  250.  
  251. -#ifdef _WIN32
  252. -               memset(sa, 0, salen);
  253. -               if (error = wintirpc_getsockopt(sd, SOL_SOCKET, SO_PROTOCOL_INFO, (char *)&proto_info, &proto_info_size) == SOCKET_ERROR) {
  254. -                       int sockerr = WSAGetLastError();
  255. -                       return -1;
  256. -               }
  257. -               af = proto_info.iAddressFamily;
  258. -#else
  259.                 if (wintirpc_getsockname(sd, sa, &salen) == -1)
  260.                         return -1;      /* errno is correctly set */
  261.  
  262.                 af = sa->sa_family;
  263.                 memset(sa, 0, salen);
  264. -#endif
  265.         } else
  266.                 af = sa->sa_family;
  267.  
  268. @@ -268,7 +395,4 @@ bindresvport_sa(sd, sa)
  269.  #endif
  270.         return (error);
  271.  }
  272. -/*
  273. -#endif
  274. -*/
  275.  #endif

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at