summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-08-12 14:09:46 +0000
committerpeter <peter@FreeBSD.org>1996-08-12 14:09:46 +0000
commit36d45bbacbf50bdee375845c4a955b90e649b036 (patch)
tree2673b5a24c426ecfb49a0d19d472c456c08a209f /lib
parentcff0cee56f8b022e93a2ce161b76444796020180 (diff)
downloadFreeBSD-src-36d45bbacbf50bdee375845c4a955b90e649b036.zip
FreeBSD-src-36d45bbacbf50bdee375845c4a955b90e649b036.tar.gz
Use the more robust and more efficient reserved port allocation mechanism
now built into bind(2). Obtained from: OpenBSD / Jason Downs / Theo de Raadt
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/rpc/bindresvport.c66
1 files changed, 45 insertions, 21 deletions
diff --git a/lib/libc/rpc/bindresvport.c b/lib/libc/rpc/bindresvport.c
index 0f20177..4411ba9 100644
--- a/lib/libc/rpc/bindresvport.c
+++ b/lib/libc/rpc/bindresvport.c
@@ -30,11 +30,14 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)bindresvport.c 1.8 88/02/08 SMI";*/
/*static char *sccsid = "from: @(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC";*/
-static char *rcsid = "$Id: bindresvport.c,v 1.3 1995/10/22 14:51:11 phk Exp $";
+/*from: OpenBSD: bindresvport.c,v 1.7 1996/07/30 16:25:47 downsj Exp */
+static char *rcsid = "$Id: bindresvport.c,v 1.4 1996/06/10 00:49:15 jraynard Exp $";
#endif
/*
* Copyright (c) 1987 by Sun Microsystems, Inc.
+ *
+ * Portions Copyright(C) 1996, Jason Downs. All rights reserved.
*/
#include <sys/types.h>
@@ -47,39 +50,60 @@ static char *rcsid = "$Id: bindresvport.c,v 1.3 1995/10/22 14:51:11 phk Exp $";
/*
* Bind a socket to a privileged IP port
*/
-int bindresvport(sd, sin)
+int
+bindresvport(sd, sin)
int sd;
struct sockaddr_in *sin;
{
- int res;
- static short port;
+ int on, old, error;
struct sockaddr_in myaddr;
- int i;
-
-#define STARTPORT 600
-#define ENDPORT (IPPORT_RESERVED - 1)
-#define NPORTS (ENDPORT - STARTPORT + 1)
+ int sinlen = sizeof(struct sockaddr_in);
if (sin == (struct sockaddr_in *)0) {
sin = &myaddr;
- bzero(sin, sizeof (*sin));
+ memset(sin, 0, sizeof(*sin));
+ sin->sin_len = sizeof(*sin);
sin->sin_family = AF_INET;
} else if (sin->sin_family != AF_INET) {
errno = EPFNOSUPPORT;
return (-1);
}
- if (port == 0) {
- port = (getpid() % NPORTS) + STARTPORT;
+
+ if (sin->sin_port == 0) {
+ int oldlen = sizeof(old);
+ error = getsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
+ &old, &oldlen);
+ if (error < 0)
+ return(error);
+
+ on = IP_PORTRANGE_LOW;
+ error = setsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
+ &on, sizeof(on));
+ if (error < 0)
+ return(error);
}
- res = -1;
- errno = EADDRINUSE;
- for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) {
- sin->sin_port = htons(port++);
- if (port > ENDPORT) {
- port = STARTPORT;
+
+ error = bind(sd, (struct sockaddr *)sin, sizeof(*sin));
+
+ if (sin->sin_port == 0) {
+ int saved_errno = errno;
+
+ if (error) {
+ if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
+ &old, sizeof(old)) < 0)
+ errno = saved_errno;
+ return (error);
+ }
+
+ if (sin != &myaddr) {
+ int sinlen = sizeof(*sin);
+
+ /* Hmm, what did the kernel assign... */
+ if (getsockname(sd, (struct sockaddr *)sin,
+ &sinlen) < 0)
+ errno = saved_errno;
+ return (error);
}
- res = bind(sd,
- (struct sockaddr *)sin, sizeof(struct sockaddr_in));
}
- return (res);
+ return (error);
}
OpenPOWER on IntegriCloud