Fwd: freeport(1)

Alejandro Colomar <[email protected]>
Newsgroups gmane.comp.gnu.inetutils.bugs
Message-ID <[email protected]>
Hi,

Bernd recommended me to consider inetutils for this program (see the 
forwarded mail), since net-tools is deprecated.

Yes, it has a race condition by the nature of the port being free at the 
time the program prints it, but the kernel will not reuse it unless all 
other ports have been used first (AFAIK), so the chances are quite low, 
and also the program for which we will use it is just some introductory 
tutorial, and not something critical.

Options for selecting the interface, and also to select a port range, 
could be implemented easily, and seem useful to me.  (Thanks, Bernd, for 
your recommendations and small review.)

Would you be interested in adding this tool to inetutils?  I would help 
maintain it.

Cheers,

Alex


-------- Forwarded Message --------

[resent from a subscribed address; again, since it didn't work...]
[D'oh, I hadn't confirmed subscription; sorry Mike for spamming you :/]

Hi,

As a side effect of doing some work for NGINX Unit, I developed the 
following program, which I think might be useful for the general public 
and not only for us.  Would you want to pick the program for the 
net-tools project?  I'd be able to help maintain it.  Also, since I'm 
also the maintainer of the Linux man-pages, you can expect that I'll 
provide a manual page for the program.

The program is as simple as it gets.  A draft for the manual page would be:


NAME
      freeport - get a random unused port number

SYNOPSIS
      freeport

DESCRIPTION
      This program prints an available IPv4 port and exits.

      The port is chosen at random from the ephemeral ports range
      (see ip(7)).

EXIT STATUS
      0    Success
      1    Error

      On error, a message is printed on standard error.


And the source code is:


$ cat freeport.c
/*
   * SPDX-License-Identifier:  GPL-2.0-or-later
   * Copyright 2022  NGINX, Inc.
   * Copyright 2022  F5, Inc.
   *
   * Author:  Alejandro Colomar <[email protected]>
   */


#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/socket.h>
#include <unistd.h>


int32_t get_free_port(void);


int
main(void)
{
	int32_t  port;

	port = get_free_port();
	if (port == -1)
		exit(EXIT_FAILURE);

	printf("%d\n", port);
	exit(EXIT_SUCCESS);
}


int32_t
get_free_port(void)
{
	int                 sfd;
	int32_t             port;
	socklen_t           len;
	struct sockaddr_in  addr;

	sfd = socket(PF_INET, SOCK_STREAM, 0);
	if (sfd == -1) {
		perror("socket()");
		return -1;
	}

	bzero(&addr, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	addr.sin_port = htons(0);  // random port

	len = sizeof(addr);
	if (bind(sfd, (struct sockaddr *) &addr, len)) {
		perror("bind()");
		goto fail;
	}

	if (getsockname(sfd, (struct sockaddr *) &addr, &len)) {
		perror("getsockname()");
		goto fail;
	}

	port = ntohs(addr.sin_port);

fail:
	close(sfd);
	return port;
}


Would you be interested in this program?
It was written on Linux, and I'm not sure about its portability (didn't 
check), so one of the things to check for adding it to net-tools would 
be that.


Cheers,
Alex

-- 
<http://www.alejandro-colomar.es/>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.