mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
Update address lookup in C TLS client to use modern methods.
The implementation using gethostbyname() was only intended to be used during prototyping but was forgotten when the code was finalized. Replace it with gettaddrinfo() which is more modern and supports IPv6. Suggested by Bruno Friedmann.
This commit is contained in:
parent
4d1060ea6b
commit
053972bfe0
@ -30,6 +30,14 @@
|
|||||||
|
|
||||||
<p>Add <id>_DARWIN_C_SOURCE</id> flag to Makefile for <proper>MacOS</proper> builds.</p>
|
<p>Add <id>_DARWIN_C_SOURCE</id> flag to Makefile for <proper>MacOS</proper> builds.</p>
|
||||||
</release-item>
|
</release-item>
|
||||||
|
|
||||||
|
<release-item>
|
||||||
|
<release-item-contributor-list>
|
||||||
|
<release-item-ideator id="bruno.friedmann"/>
|
||||||
|
</release-item-contributor-list>
|
||||||
|
|
||||||
|
<p>Update address lookup in C TLS client to use modern methods.</p>
|
||||||
|
</release-item>
|
||||||
</release-improvement-list>
|
</release-improvement-list>
|
||||||
|
|
||||||
<release-development-list>
|
<release-development-list>
|
||||||
@ -6128,6 +6136,11 @@
|
|||||||
<contributor-id type="github">baburdick</contributor-id>
|
<contributor-id type="github">baburdick</contributor-id>
|
||||||
</contributor>
|
</contributor>
|
||||||
|
|
||||||
|
<contributor id="bruno.friedmann">
|
||||||
|
<contributor-name-display>Bruno Friedmann</contributor-name-display>
|
||||||
|
<contributor-id type="github">tigerfoot</contributor-id>
|
||||||
|
</contributor>
|
||||||
|
|
||||||
<contributor id="camilo.aguilar">
|
<contributor id="camilo.aguilar">
|
||||||
<contributor-name-display>Camilo Aguilar</contributor-name-display>
|
<contributor-name-display>Camilo Aguilar</contributor-name-display>
|
||||||
<contributor-id type="github">c4milo</contributor-id>
|
<contributor-id type="github">c4milo</contributor-id>
|
||||||
|
@ -287,24 +287,43 @@ tlsClientOpen(TlsClient *this)
|
|||||||
|
|
||||||
TRY_BEGIN()
|
TRY_BEGIN()
|
||||||
{
|
{
|
||||||
// Resolve the ip address. We'll just blindly take the first address that comes up.
|
// Set hits that narrow the type of address we are looking for -- we'll take ipv4 or ipv6
|
||||||
struct hostent *host_entry = NULL;
|
struct addrinfo hints;
|
||||||
|
|
||||||
if ((host_entry = gethostbyname(strPtr(this->host))) == NULL)
|
memset(&hints, 0, sizeof hints);
|
||||||
THROW_FMT(HostConnectError, "unable to resolve host '%s'", strPtr(this->host));
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
// Connect to the server
|
// Convert the port to a zero-terminated string for use with getaddrinfo()
|
||||||
this->socket = socket(AF_INET, SOCK_STREAM, 0);
|
char port[32];
|
||||||
|
cvtUIntToZ(this->port, port, sizeof(port));
|
||||||
|
|
||||||
|
// Get an address for the host. We are only going to try the first address returned.
|
||||||
|
struct addrinfo *hostAddress;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if ((result = getaddrinfo(strPtr(this->host), port, &hints, &hostAddress)) != 0)
|
||||||
|
{
|
||||||
|
THROW_FMT(
|
||||||
|
HostConnectError, "unable to get address for '%s': [%d] %s", strPtr(this->host), result,
|
||||||
|
gai_strerror(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect to the host
|
||||||
|
TRY_BEGIN()
|
||||||
|
{
|
||||||
|
this->socket = socket(hostAddress->ai_family, hostAddress->ai_socktype, hostAddress->ai_protocol);
|
||||||
THROW_ON_SYS_ERROR(this->socket == -1, HostConnectError, "unable to create socket");
|
THROW_ON_SYS_ERROR(this->socket == -1, HostConnectError, "unable to create socket");
|
||||||
|
|
||||||
struct sockaddr_in socketAddr;
|
if (connect(this->socket, hostAddress->ai_addr, hostAddress->ai_addrlen) == -1)
|
||||||
memset(&socketAddr, 0, sizeof(socketAddr));
|
|
||||||
socketAddr.sin_family = AF_INET;
|
|
||||||
socketAddr.sin_addr.s_addr = inet_addr(inet_ntoa(*((struct in_addr*)host_entry->h_addr_list[0])));
|
|
||||||
socketAddr.sin_port = htons((uint16_t)this->port);
|
|
||||||
|
|
||||||
if (connect(this->socket, (struct sockaddr *)&socketAddr, sizeof(socketAddr)) == -1)
|
|
||||||
THROW_SYS_ERROR_FMT(HostConnectError, "unable to connect to '%s:%u'", strPtr(this->host), this->port);
|
THROW_SYS_ERROR_FMT(HostConnectError, "unable to connect to '%s:%u'", strPtr(this->host), this->port);
|
||||||
|
}
|
||||||
|
FINALLY()
|
||||||
|
{
|
||||||
|
freeaddrinfo(hostAddress);
|
||||||
|
}
|
||||||
|
TRY_END();
|
||||||
|
|
||||||
// Enable TCP keepalives
|
// Enable TCP keepalives
|
||||||
int socketValue = 1;
|
int socketValue = 1;
|
||||||
|
@ -121,7 +121,8 @@ testRun(void)
|
|||||||
// Connection errors
|
// Connection errors
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), 9443, 0, true, NULL, NULL), "new client");
|
TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), 9443, 0, true, NULL, NULL), "new client");
|
||||||
TEST_ERROR(tlsClientOpen(client), HostConnectError, "unable to resolve host '99.99.99.99.99'");
|
TEST_ERROR(
|
||||||
|
tlsClientOpen(client), HostConnectError, "unable to get address for '99.99.99.99.99': [-2] Name or service not known");
|
||||||
|
|
||||||
TEST_ASSIGN(client, tlsClientNew(strNew("localhost"), 9443, 100, true, NULL, NULL), "new client");
|
TEST_ASSIGN(client, tlsClientNew(strNew("localhost"), 9443, 100, true, NULL, NULL), "new client");
|
||||||
TEST_ERROR(tlsClientOpen(client), HostConnectError, "unable to connect to 'localhost:9443': [111] Connection refused");
|
TEST_ERROR(tlsClientOpen(client), HostConnectError, "unable to connect to 'localhost:9443': [111] Connection refused");
|
||||||
|
@ -5,6 +5,18 @@
|
|||||||
obj:*/libcrypto.so*
|
obj:*/libcrypto.so*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# This is an issue on CentOS 7 after calling getaddrinfo() even if freeaddrinfo() is called as well
|
||||||
|
{
|
||||||
|
ignore_free_error_after_getaddrinfo
|
||||||
|
Memcheck:Free
|
||||||
|
fun:free
|
||||||
|
fun:__libc_freeres
|
||||||
|
fun:_vgnU_freeres
|
||||||
|
fun:__run_exit_handlers
|
||||||
|
fun:exit
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
# This only seems to be an issue on Ubuntu 12.04 -- probably due to the old version of Valgrind
|
# This only seems to be an issue on Ubuntu 12.04 -- probably due to the old version of Valgrind
|
||||||
{
|
{
|
||||||
ignore_libcrypto_uninit_cond_jump
|
ignore_libcrypto_uninit_cond_jump
|
||||||
|
Loading…
Reference in New Issue
Block a user