Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support IPv6 #213

Merged
merged 7 commits into from
Mar 19, 2024
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 34 additions & 26 deletions mbus/mbus-tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,8 @@
#include <limits.h>
#include <fcntl.h>

#include <sys/socket.h>
#include <sys/types.h>

#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>

#include <stdio.h>
Expand All @@ -27,6 +24,7 @@
#include "mbus-tcp.h"

#define PACKET_BUFF_SIZE 2048
#define MAX_PORT_SIZE 6 // Size of port number + NULL char

static int tcp_timeout_sec = 4;
static int tcp_timeout_usec = 0;
Expand All @@ -38,11 +36,11 @@ int
mbus_tcp_connect(mbus_handle *handle)
{
char error_str[128], *host;
struct hostent *host_addr;
struct sockaddr_in s;
struct addrinfo hints, *servinfo, *p;
struct timeval time_out;
mbus_tcp_data *tcp_data;
uint16_t port;
char port[MAX_PORT_SIZE];
int status;

if (handle == NULL)
return -1;
Expand All @@ -51,39 +49,49 @@ mbus_tcp_connect(mbus_handle *handle)
if (tcp_data == NULL || tcp_data->host == NULL)
return -1;

host = tcp_data->host;
port = tcp_data->port;

//
// create the TCP connection
//
if ((handle->fd = socket(AF_INET,SOCK_STREAM, 0)) < 0)
// Check if port is in allowed range
if ((tcp_data->port < 0) || (tcp_data->port > 0xFFFF))
lategoodbye marked this conversation as resolved.
Show resolved Hide resolved
{
snprintf(error_str, sizeof(error_str), "%s: failed to setup a socket.", __PRETTY_FUNCTION__);
mbus_error_str_set(error_str);
snprintf(error_str, sizeof(error_str), "%s: Invalid port: %d", __PRETTY_FUNCTION__, tcp_data->port);
return -1;
}

s.sin_family = AF_INET;
s.sin_port = htons(port);
host = tcp_data->host;
snprintf(port, MAX_PORT_SIZE, "%d", tcp_data->port);

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;

/* resolve hostname */
if ((host_addr = gethostbyname(host)) == NULL)
{
snprintf(error_str, sizeof(error_str), "%s: unknown host: %s", __PRETTY_FUNCTION__, host);
if ((status = getaddrinfo(host, port, &hints, &servinfo)) != 0) {
snprintf(error_str, sizeof(error_str), "%s: getaddrinfo: %s", __PRETTY_FUNCTION__, gai_strerror(status));
mbus_error_str_set(error_str);
return -1;
}

memcpy((void *)(&s.sin_addr), (void *)(host_addr->h_addr), host_addr->h_length);
// loop through all the results and connect to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
lategoodbye marked this conversation as resolved.
Show resolved Hide resolved
if ((handle->fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
continue;
}

if (connect(handle->fd, (struct sockaddr *)&s, sizeof(s)) < 0)
{
snprintf(error_str, sizeof(error_str), "%s: Failed to establish connection to %s:%d", __PRETTY_FUNCTION__, host, port);
if (connect(handle->fd, p->ai_addr, p->ai_addrlen) == -1) {
close(handle->fd);
continue;
}

break; // if we get here, we must have connected successfully
}

if (p == NULL) {
snprintf(error_str, sizeof(error_str), "%s: failed to connect", __PRETTY_FUNCTION__);
lategoodbye marked this conversation as resolved.
Show resolved Hide resolved
mbus_error_str_set(error_str);
return -1;
}

// Free addr info, we do not need it anymore
freeaddrinfo(servinfo);
lategoodbye marked this conversation as resolved.
Show resolved Hide resolved

// Set a timeout
time_out.tv_sec = tcp_timeout_sec; // seconds
time_out.tv_usec = tcp_timeout_usec; // microseconds
Expand Down