aseqnet: use getaddrinfo() instead obsolete gethostbyname()

- modernize code (preparation for IPv6)

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2021-08-09 18:10:56 +02:00
parent f076518254
commit c8e5762750

View file

@ -21,6 +21,7 @@
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <locale.h>
#include <alsa/asoundlib.h>
@ -38,10 +39,9 @@ static void init_buf(void);
static void init_pollfds(void);
static void close_files(void);
static void init_seq(char *source, char *dest, char *name);
static int get_port(char *service);
static void sigterm_exit(int sig);
static void init_server(int port);
static void init_client(char *server, int port);
static void init_server(const char *port);
static void init_client(const char *server, const char *port);
static void do_loop(void);
static int copy_local_to_remote(void);
static int copy_remote_to_local(int fd);
@ -49,7 +49,7 @@ static int copy_remote_to_local(int fd);
/*
* default TCP port number
*/
#define DEFAULT_PORT 40002
#define DEFAULT_PORT "40002"
/*
* local input buffer
@ -97,7 +97,7 @@ static const struct option long_option[] = {
int main(int argc, char **argv)
{
int c;
int port = DEFAULT_PORT;
char *port = DEFAULT_PORT;
char *source = NULL, *dest = NULL;
char *name = NULL;
@ -109,10 +109,7 @@ int main(int argc, char **argv)
while ((c = getopt_long(argc, argv, "p:s:d:n:,vi", long_option, NULL)) != -1) {
switch (c) {
case 'p':
if (isdigit(*optarg))
port = atoi(optarg);
else
port = get_port(optarg);
port = optarg;
break;
case 's':
source = optarg;
@ -307,19 +304,25 @@ static void init_seq(char *source, char *dest, char* name)
}
}
/*
* convert from string to TCP port number
* translate the binary network address to ASCII
*/
static int get_port(char *service)
static void get_net_addr(struct addrinfo *rp, char *buf, size_t buflen)
{
struct servent *sp;
void *ptr;
if ((sp = getservbyname(service, "tcp")) == NULL){
fprintf(stderr, _("service '%s' is not found in /etc/services\n"), service);
return -1;
switch (rp->ai_family) {
case AF_INET:
ptr = &((struct sockaddr_in *) rp->ai_addr)->sin_addr;
break;
case AF_INET6:
ptr = &((struct sockaddr_in6 *) rp->ai_addr)->sin6_addr;
break;
default:
ptr = NULL;
}
return sp->s_port;
buf[buflen-1] = '\0';
inet_ntop(rp->ai_family, ptr, buf, buflen-1);
}
/*
@ -335,30 +338,48 @@ static void sigterm_exit(int sig)
/*
* initialize network server
*/
static void init_server(int port)
static void init_server(const char *port)
{
struct addrinfo hints;
struct addrinfo *result, *rp;
char buf[100];
int i;
int curstate = 1;
struct sockaddr_in addr;
int save_errno = 0;
memset(&addr, 0, sizeof(addr));
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
if (getaddrinfo(NULL, port, &hints, &result) < 0) {
fprintf(stderr, _("can't get address\n"));
exit(1);
}
for (rp = result; rp != NULL; rp = rp->ai_next) {
if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
perror("create socket");
exit(1);
}
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate));
/* the return value is ignored.. */
if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("can't bind");
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) {
perror("setsockopt");
exit(1);
}
if (verbose) {
get_net_addr(rp, buf, sizeof(buf));
fprintf(stderr, _("connecting to: %s\n"), buf);
}
if (bind(sockfd, rp->ai_addr, rp->ai_addrlen) == 0)
break;
save_errno = errno;
close(sockfd);
}
if (rp == NULL) {
errno = save_errno;
perror("bind");
exit(1);
}
freeaddrinfo(result);
if (listen(sockfd, 5) < 0) {
perror("can't listen");
@ -402,13 +423,25 @@ static void start_connection(void)
/*
* initialize network client
*/
static void init_client(char *server, int port)
static void init_client(const char *server, const char *port)
{
struct sockaddr_in addr;
struct hostent *host;
struct addrinfo hints;
struct addrinfo *result, *rp;
char buf[100];
int curstate = 1;
int fd;
int save_errno = 0;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if (getaddrinfo(server, port, &hints, &result) < 0) {
fprintf(stderr, _("can't get address %s\n"), server);
exit(1);
}
for (rp = result; rp != NULL; rp = rp->ai_next) {
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
perror("create socket");
exit(1);
@ -417,17 +450,21 @@ static void init_client(char *server, int port)
perror("setsockopt");
exit(1);
}
if ((host = gethostbyname(server)) == NULL){
fprintf(stderr, _("can't get address %s\n"), server);
exit(1);
if (verbose) {
get_net_addr(rp, buf, sizeof(buf));
fprintf(stderr, _("connecting to: %s\n"), buf);
}
addr.sin_port = htons(port);
addr.sin_family = AF_INET;
memcpy(&addr.sin_addr, host->h_addr, host->h_length);
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
if (connect(fd, rp->ai_addr, rp->ai_addrlen) == 0)
break;
save_errno = errno;
close(fd);
}
if (rp == NULL) {
errno = save_errno;
perror("connect");
exit(1);
}
freeaddrinfo(result);
if (verbose)
fprintf(stderr, _("ok.. connected\n"));
netfd[0] = fd;