Watt-32 tcp/ip  2.2 dev-rel.10
ports.c
Go to the documentation of this file.
1 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <limits.h>
11 
12 #include "copyrigh.h"
13 #include "wattcp.h"
14 #include "strings.h"
15 #include "misc.h"
16 #include "run.h"
17 #include "pctcp.h"
18 
19 #if (DOSX)
20  #define MAX_PORT USHRT_MAX /* 65535 */
21 #else
22  #define MAX_PORT 5000
23 #endif
24 
25 /*
26  * Allocated local TCP/UDP-ports start at 1025 (empherical range). We can
27  * at max handle MAX_PORT local ports. Use an array of 'fd_set' to check which
28  * port is free or not.
29  */
30 #define MIN_PORT 1025
31 #define NUM_FD_SETS (1 + (MAX_PORT / (8*sizeof(fd_set))))
32 
33 int use_rand_lport = TRUE;
34 static fd_set *lport_inuse;
35 
39 static void exit_localport (void)
40 {
41  if (!_watt_fatal_error && lport_inuse)
42  free (lport_inuse);
43  lport_inuse = NULL;
44 }
45 
52 WORD init_localport (void)
53 {
54  size_t size = sizeof(fd_set) * NUM_FD_SETS;
55 
56  lport_inuse = calloc (size, 1);
57  if (!lport_inuse)
58  return (0);
59 
60  RUNDOWN_ADD (exit_localport, 303);
61  return (MAX_PORT);
62 }
63 
64 /*
65  * Return unused local port
66  * - port = 0 -> normal port,
67  * - port = 1 -> special port (513-1023)
68  *
69  * `linger' is set if port shall be matched against "sleeping" ports.
70  * Local tcp-ports should not be reused 60sec (2*MSL) after they have
71  * been closed. Note this is NOT related to 'sock_delay'.
72  */
73 WORD find_free_port (WORD port, BOOL linger)
74 {
75  WORD p, lo_port, hi_port;
76 
77  if (!lport_inuse)
78  return (port);
79 
80  if (port > 0 && port < USHRT_MAX) /* return port as-is */
81  return (port);
82 
83  if (port == 0)
84  {
85  if (use_rand_lport)
86  lo_port = Random (MIN_PORT, 1500);
87  else lo_port = MIN_PORT;
88  }
89  else
90  lo_port = 513;
91 
92  hi_port = MAX_PORT; /* our empherical max-port */
93 
94  for (p = lo_port; p <= hi_port; p++)
95  {
96  if (linger && FD_ISSET(p,lport_inuse)) /* inuse, try next */
97  continue;
98 
99  if (_udp_allsocs)
100  {
101  const _udp_Socket *udp = _udp_allsocs;
102 
103  while (udp->next && udp->myport != p)
104  udp = udp->next;
105  if (udp->myport == p)
106  continue;
107  }
108 #if !defined(USE_UDP_ONLY)
109  if (_tcp_allsocs)
110  {
111  const _tcp_Socket *tcp = _tcp_allsocs;
112 
113  while (tcp->next && tcp->myport != p)
114  tcp = tcp->next;
115  if (tcp->myport == p)
116  continue;
117  }
118 #endif
119  break;
120  }
121  FD_SET (p, lport_inuse);
122  return (p);
123 }
124 
125 #if defined(USE_BSD_API)
126 /*
127  * Set the "lport_inuse" bit for a local port.
128  * 'port' is in host order.
129  * Returns original state or -1 if port above our range.
130  */
131 int grab_localport (WORD port)
132 {
133  int rc;
134 
135 #if (MAX_PORT < USHRT_MAX)
136  if (port > MAX_PORT)
137  return (-1);
138 #endif
139 
140  if (!lport_inuse)
141  return (-1);
142 
143  rc = FD_ISSET (port, lport_inuse);
144  FD_SET (port, lport_inuse);
145  return (rc);
146 }
147 #endif
148 
149 /*
150  * Clear the "lport_inuse" bit for a local port.
151  * 'port' is in host order. Port 0 is not considered a port.
152  * Returns original state or -1 if port above our range.
153  */
154 int reuse_localport (WORD port)
155 {
156  int rc;
157 
158 #if (MAX_PORT < USHRT_MAX)
159  if (port > MAX_PORT)
160  return (-1);
161 #endif
162 
163  if (!lport_inuse)
164  return (-1);
165 
166  rc = FD_ISSET (port, lport_inuse);
167  FD_CLR (port, lport_inuse);
168  return (rc);
169 }
170 
171 #if !defined(USE_UDP_ONLY)
172 /*
173  * Reuse local port now if not owned by a STREAM-socket.
174  * Otherwise let socket daemon free local port when linger period
175  * expires. We don't care about rapid reuse of local ports associated
176  * with DGRAM-sockets.
177  */
178 int maybe_reuse_localport (_tcp_Socket *s)
179 {
180 #if defined(USE_BSD_API)
181  if (!_bsd_socket_hook || !(*_bsd_socket_hook)(BSO_FIND_SOCK,s))
182  return reuse_localport (s->myport);
183  return (0);
184 #else
185  return reuse_localport (s->myport);
186 #endif
187 }
188 #endif /* USE_UDP_ONLY */
Definition: wtypes.h:197
unsigned W32_CALL Random(unsigned a, unsigned b)
Returns a random integer in range [a..b].
Definition: misc.c:742
WORD init_localport(void)
Allocate the "lport_inuse" bit-array from heap.
Definition: ports.c:52
_udp_Socket * _udp_allsocs
list of udp-sockets
Definition: pctcp.c:73
Core definitions.
Definition: socket.h:127
static void exit_localport(void)
Free allocated memory.
Definition: ports.c:39
void *MS_CDECL * _bsd_socket_hook(enum BSD_SOCKET_OPS op,...)
This hook is to prevent the BSD-socket API being linked in by default.
BOOL _watt_fatal_error
Definition: misc.c:60
_tcp_Socket * _tcp_allsocs
list of tcp-sockets
Definition: pctcp.c:137
struct tcp_Socket * next
link to next tcp-socket
Definition: wattcp.h:613