mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2026-06-20 01:17:49 +02:00
Split session functionality of SocketClient out into SocketSession.
This abstraction allows the session code to be shared between the socket client and (upcoming) server code. There should no difference in how the code works -- only the organization has changed. Note that no changes to the tests were required. This same abstraction will be required for TlsClient but that will be done in a separate commit because it requires test changes.
This commit is contained in:
@@ -33,6 +33,14 @@
|
||||
|
||||
<p>Simplify storage driver info and list functions.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<release-item-contributor-list>
|
||||
<release-item-reviewer id="cynthia.shang"/>
|
||||
</release-item-contributor-list>
|
||||
|
||||
<p>Split session functionality of <code>SocketClient</code> out into <code>SocketSession</code>.</p>
|
||||
</release-item>
|
||||
</release-development-list>
|
||||
</release-core-list>
|
||||
</release>
|
||||
|
||||
@@ -76,6 +76,7 @@ SRCS = \
|
||||
common/io/read.c \
|
||||
common/io/socket/client.c \
|
||||
common/io/socket/common.c \
|
||||
common/io/socket/session.c \
|
||||
common/io/tls/client.c \
|
||||
common/io/write.c \
|
||||
common/ini.c \
|
||||
|
||||
@@ -13,6 +13,7 @@ Socket Client
|
||||
#include "common/log.h"
|
||||
#include "common/io/socket/client.h"
|
||||
#include "common/io/socket/common.h"
|
||||
#include "common/io/socket/session.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/type/object.h"
|
||||
#include "common/wait.h"
|
||||
@@ -31,25 +32,10 @@ struct SocketClient
|
||||
String *host; // Hostname or IP address
|
||||
unsigned int port; // Port to connect to host on
|
||||
TimeMSec timeout; // Timeout for any i/o operation (connect, read, etc.)
|
||||
|
||||
int fd; // File descriptor
|
||||
};
|
||||
|
||||
OBJECT_DEFINE_GET(Fd, , SOCKET_CLIENT, int, fd);
|
||||
OBJECT_DEFINE_GET(Host, const, SOCKET_CLIENT, const String *, host);
|
||||
OBJECT_DEFINE_GET(Port, const, SOCKET_CLIENT, unsigned int, port);
|
||||
|
||||
OBJECT_DEFINE_MOVE(SOCKET_CLIENT);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free connection
|
||||
***********************************************************************************************************************************/
|
||||
OBJECT_DEFINE_FREE_RESOURCE_BEGIN(SOCKET_CLIENT, LOG, logLevelTrace)
|
||||
{
|
||||
close(this->fd);
|
||||
}
|
||||
OBJECT_DEFINE_FREE_RESOURCE_END(LOG);
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
SocketClient *
|
||||
sckClientNew(const String *host, unsigned int port, TimeMSec timeout)
|
||||
@@ -74,9 +60,6 @@ sckClientNew(const String *host, unsigned int port, TimeMSec timeout)
|
||||
.host = strDup(host),
|
||||
.port = port,
|
||||
.timeout = timeout,
|
||||
|
||||
// Initialize file descriptor to -1 so we know when the socket is disconnected
|
||||
.fd = -1,
|
||||
};
|
||||
|
||||
sckClientStatLocal.object++;
|
||||
@@ -87,7 +70,7 @@ sckClientNew(const String *host, unsigned int port, TimeMSec timeout)
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
SocketSession *
|
||||
sckClientOpen(SocketClient *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace)
|
||||
@@ -95,7 +78,8 @@ sckClientOpen(SocketClient *this)
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
CHECK(this->fd == -1);
|
||||
|
||||
SocketSession *result = NULL;
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
@@ -107,6 +91,7 @@ sckClientOpen(SocketClient *this)
|
||||
{
|
||||
// Assume there will be no retry
|
||||
retry = false;
|
||||
int fd = -1;
|
||||
|
||||
TRY_BEGIN()
|
||||
{
|
||||
@@ -124,26 +109,24 @@ sckClientOpen(SocketClient *this)
|
||||
|
||||
// Get an address for the host. We are only going to try the first address returned.
|
||||
struct addrinfo *hostAddress;
|
||||
int result;
|
||||
int resultAddr;
|
||||
|
||||
if ((result = getaddrinfo(strPtr(this->host), port, &hints, &hostAddress)) != 0)
|
||||
if ((resultAddr = 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));
|
||||
HostConnectError, "unable to get address for '%s': [%d] %s", strPtr(this->host), resultAddr,
|
||||
gai_strerror(resultAddr));
|
||||
}
|
||||
|
||||
// Connect to the host
|
||||
TRY_BEGIN()
|
||||
{
|
||||
this->fd = socket(hostAddress->ai_family, hostAddress->ai_socktype, hostAddress->ai_protocol);
|
||||
THROW_ON_SYS_ERROR(this->fd == -1, HostConnectError, "unable to create socket");
|
||||
fd = socket(hostAddress->ai_family, hostAddress->ai_socktype, hostAddress->ai_protocol);
|
||||
THROW_ON_SYS_ERROR(fd == -1, HostConnectError, "unable to create socket");
|
||||
|
||||
memContextCallbackSet(this->memContext, sckClientFreeResource, this);
|
||||
sckOptionSet(fd);
|
||||
|
||||
sckOptionSet(this->fd);
|
||||
|
||||
if (connect(this->fd, hostAddress->ai_addr, hostAddress->ai_addrlen) == -1)
|
||||
if (connect(fd, hostAddress->ai_addr, hostAddress->ai_addrlen) == -1)
|
||||
THROW_SYS_ERROR_FMT(HostConnectError, "unable to connect to '%s:%u'", strPtr(this->host), this->port);
|
||||
}
|
||||
FINALLY()
|
||||
@@ -152,11 +135,21 @@ sckClientOpen(SocketClient *this)
|
||||
}
|
||||
TRY_END();
|
||||
|
||||
// Create the session
|
||||
MEM_CONTEXT_PRIOR_BEGIN()
|
||||
{
|
||||
result = sckSessionNew(fd, this->host, this->port, this->timeout);
|
||||
}
|
||||
MEM_CONTEXT_PRIOR_END();
|
||||
|
||||
// Connection was successful
|
||||
connected = true;
|
||||
}
|
||||
CATCH_ANY()
|
||||
{
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
|
||||
// Retry if wait time has not expired
|
||||
if (waitMore(wait))
|
||||
{
|
||||
@@ -165,8 +158,6 @@ sckClientOpen(SocketClient *this)
|
||||
|
||||
sckClientStatLocal.retry++;
|
||||
}
|
||||
|
||||
sckClientClose(this);
|
||||
}
|
||||
TRY_END();
|
||||
}
|
||||
@@ -179,69 +170,9 @@ sckClientOpen(SocketClient *this)
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
FUNCTION_LOG_RETURN(SOCKET_SESSION, result);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
sckClientReadWait(SocketClient *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(SOCKET_CLIENT, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->fd != -1);
|
||||
|
||||
// Initialize the file descriptor set used for select
|
||||
fd_set selectSet;
|
||||
FD_ZERO(&selectSet);
|
||||
|
||||
// We know the socket is not negative because it passed error handling, so it is safe to cast to unsigned
|
||||
FD_SET((unsigned int)this->fd, &selectSet);
|
||||
|
||||
// Initialize timeout struct used for select. Recreate this structure each time since Linux (at least) will modify it.
|
||||
struct timeval timeoutSelect;
|
||||
timeoutSelect.tv_sec = (time_t)(this->timeout / MSEC_PER_SEC);
|
||||
timeoutSelect.tv_usec = (time_t)(this->timeout % MSEC_PER_SEC * 1000);
|
||||
|
||||
// Determine if there is data to be read
|
||||
int result = select(this->fd + 1, &selectSet, NULL, NULL, &timeoutSelect);
|
||||
THROW_ON_SYS_ERROR_FMT(result == -1, AssertError, "unable to select from '%s:%u'", strPtr(this->host), this->port);
|
||||
|
||||
// If no data available after time allotted then error
|
||||
if (!result)
|
||||
{
|
||||
THROW_FMT(
|
||||
FileReadError, "timeout after %" PRIu64 "ms waiting for read from '%s:%u'", this->timeout, strPtr(this->host),
|
||||
this->port);
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
sckClientClose(SocketClient *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(SOCKET_CLIENT, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
// Close the socket
|
||||
if (this->fd != -1)
|
||||
{
|
||||
memContextCallbackClear(this->memContext);
|
||||
sckClientFreeResource(this);
|
||||
this->fd = -1;
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
String *
|
||||
sckClientStatStr(void)
|
||||
|
||||
@@ -17,6 +17,7 @@ Object type
|
||||
typedef struct SocketClient SocketClient;
|
||||
|
||||
#include "common/io/read.h"
|
||||
#include "common/io/socket/session.h"
|
||||
#include "common/io/write.h"
|
||||
#include "common/time.h"
|
||||
#include "common/type/string.h"
|
||||
@@ -40,29 +41,11 @@ SocketClient *sckClientNew(const String *host, unsigned int port, TimeMSec timeo
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
// Open the connection
|
||||
void sckClientOpen(SocketClient *this);
|
||||
SocketSession *sckClientOpen(SocketClient *this);
|
||||
|
||||
// Wait for the socket to be readable
|
||||
void sckClientReadWait(SocketClient *this);
|
||||
|
||||
// Close the connection
|
||||
void sckClientClose(SocketClient *this);
|
||||
|
||||
// Move the socket to a new parent mem context
|
||||
// Move to a new parent mem context
|
||||
SocketClient *sckClientMove(SocketClient *this, MemContext *parentNew);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
// Socket file descriptor
|
||||
int sckClientFd(SocketClient *this);
|
||||
|
||||
// Socket host
|
||||
const String *sckClientHost(const SocketClient *this);
|
||||
|
||||
// Socket port
|
||||
unsigned int sckClientPort(const SocketClient *this);
|
||||
|
||||
// Statistics as a formatted string
|
||||
String *sckClientStatStr(void);
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/***********************************************************************************************************************************
|
||||
Socket Session
|
||||
***********************************************************************************************************************************/
|
||||
#include "build.auto.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/log.h"
|
||||
#include "common/io/socket/client.h"
|
||||
#include "common/io/socket/common.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/type/object.h"
|
||||
#include "common/wait.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct SocketSession
|
||||
{
|
||||
MemContext *memContext; // Mem context
|
||||
int fd; // File descriptor
|
||||
String *host; // Hostname or IP address
|
||||
unsigned int port; // Port to connect to host on
|
||||
TimeMSec timeout; // Timeout for any i/o operation (connect, read, etc.)
|
||||
};
|
||||
|
||||
OBJECT_DEFINE_GET(Fd, , SOCKET_SESSION, int, fd);
|
||||
OBJECT_DEFINE_GET(Host, const, SOCKET_SESSION, const String *, host);
|
||||
OBJECT_DEFINE_GET(Port, const, SOCKET_SESSION, unsigned int, port);
|
||||
|
||||
OBJECT_DEFINE_FREE(SOCKET_SESSION);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free connection
|
||||
***********************************************************************************************************************************/
|
||||
OBJECT_DEFINE_FREE_RESOURCE_BEGIN(SOCKET_SESSION, LOG, logLevelTrace)
|
||||
{
|
||||
close(this->fd);
|
||||
}
|
||||
OBJECT_DEFINE_FREE_RESOURCE_END(LOG);
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
SocketSession *
|
||||
sckSessionNew(int fd, const String *host, unsigned int port, TimeMSec timeout)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug)
|
||||
FUNCTION_LOG_PARAM(INT, fd);
|
||||
FUNCTION_LOG_PARAM(STRING, host);
|
||||
FUNCTION_LOG_PARAM(UINT, port);
|
||||
FUNCTION_LOG_PARAM(TIME_MSEC, timeout);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(fd != -1);
|
||||
ASSERT(host != NULL);
|
||||
|
||||
SocketSession *this = NULL;
|
||||
|
||||
MEM_CONTEXT_NEW_BEGIN("SocketSession")
|
||||
{
|
||||
this = memNew(sizeof(SocketSession));
|
||||
|
||||
*this = (SocketSession)
|
||||
{
|
||||
.memContext = MEM_CONTEXT_NEW(),
|
||||
.fd = fd,
|
||||
.host = strDup(host),
|
||||
.port = port,
|
||||
.timeout = timeout,
|
||||
};
|
||||
|
||||
memContextCallbackSet(this->memContext, sckSessionFreeResource, this);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
FUNCTION_LOG_RETURN(SOCKET_SESSION, this);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
sckSessionReadWait(SocketSession *this)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(SOCKET_SESSION, this);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->fd != -1);
|
||||
|
||||
// Initialize the file descriptor set used for select
|
||||
fd_set selectSet;
|
||||
FD_ZERO(&selectSet);
|
||||
|
||||
// We know the socket is not negative because it passed error handling, so it is safe to cast to unsigned
|
||||
FD_SET((unsigned int)this->fd, &selectSet);
|
||||
|
||||
// Initialize timeout struct used for select. Recreate this structure each time since Linux (at least) will modify it.
|
||||
struct timeval timeoutSelect;
|
||||
timeoutSelect.tv_sec = (time_t)(this->timeout / MSEC_PER_SEC);
|
||||
timeoutSelect.tv_usec = (time_t)(this->timeout % MSEC_PER_SEC * 1000);
|
||||
|
||||
// Determine if there is data to be read
|
||||
int result = select(this->fd + 1, &selectSet, NULL, NULL, &timeoutSelect);
|
||||
THROW_ON_SYS_ERROR_FMT(result == -1, AssertError, "unable to select from '%s:%u'", strPtr(this->host), this->port);
|
||||
|
||||
// If no data available after time allotted then error
|
||||
if (!result)
|
||||
{
|
||||
THROW_FMT(
|
||||
FileReadError, "timeout after %" PRIu64 "ms waiting for read from '%s:%u'", this->timeout, strPtr(this->host),
|
||||
this->port);
|
||||
}
|
||||
|
||||
FUNCTION_LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
String *
|
||||
sckSessionToLog(const SocketSession *this)
|
||||
{
|
||||
return strNewFmt("{fd: %d, host: %s, port: %u, timeout: %" PRIu64 "}", this->fd, strPtr(this->host), this->port, this->timeout);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/***********************************************************************************************************************************
|
||||
Socket Session
|
||||
|
||||
A simple socket session intended to allow access to services that are exposed via a socket.
|
||||
|
||||
Currently this is not a full-featured session and is only intended to isolate socket functionality from the tls code.
|
||||
***********************************************************************************************************************************/
|
||||
#ifndef COMMON_IO_SOCKET_SESSION_H
|
||||
#define COMMON_IO_SOCKET_SESSION_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
#define SOCKET_SESSION_TYPE SocketSession
|
||||
#define SOCKET_SESSION_PREFIX sckSession
|
||||
|
||||
typedef struct SocketSession SocketSession;
|
||||
|
||||
#include "common/time.h"
|
||||
#include "common/type/string.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructors
|
||||
***********************************************************************************************************************************/
|
||||
SocketSession *sckSessionNew(int fd, const String *host, unsigned int port, TimeMSec timeout);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
// Wait for the socket to be readable
|
||||
void sckSessionReadWait(SocketSession *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
// Socket file descriptor
|
||||
int sckSessionFd(SocketSession *this);
|
||||
|
||||
// Socket host
|
||||
const String *sckSessionHost(const SocketSession *this);
|
||||
|
||||
// Socket port
|
||||
unsigned int sckSessionPort(const SocketSession *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void sckSessionFree(SocketSession *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
String *sckSessionToLog(const SocketSession *this);
|
||||
|
||||
#define FUNCTION_LOG_SOCKET_SESSION_TYPE \
|
||||
SocketSession *
|
||||
#define FUNCTION_LOG_SOCKET_SESSION_FORMAT(value, buffer, bufferSize) \
|
||||
FUNCTION_LOG_STRING_OBJECT_FORMAT(value, sckSessionToLog, buffer, bufferSize)
|
||||
|
||||
#endif
|
||||
+20
-11
@@ -34,8 +34,9 @@ struct TlsClient
|
||||
MemContext *memContext; // Mem context
|
||||
TimeMSec timeout; // Timeout for any i/o operation (connect, read, etc.)
|
||||
bool verifyPeer; // Should the peer (server) certificate be verified?
|
||||
SocketClient *socket; // Client socket
|
||||
SocketClient *socketClient; // Socket client
|
||||
|
||||
SocketSession *socketSession; // Socket session
|
||||
SSL_CTX *context; // TLS context
|
||||
SSL *session; // TLS session on the socket
|
||||
|
||||
@@ -132,7 +133,7 @@ tlsClientNew(SocketClient *socket, TimeMSec timeout, bool verifyPeer, const Stri
|
||||
*this = (TlsClient)
|
||||
{
|
||||
.memContext = MEM_CONTEXT_NEW(),
|
||||
.socket = sckClientMove(socket, MEM_CONTEXT_NEW()),
|
||||
.socketClient = sckClientMove(socket, MEM_CONTEXT_NEW()),
|
||||
.timeout = timeout,
|
||||
.verifyPeer = verifyPeer,
|
||||
};
|
||||
@@ -342,7 +343,7 @@ tlsClientRead(THIS_VOID, Buffer *buffer, bool block)
|
||||
{
|
||||
// If no tls data pending then check the socket
|
||||
if (!SSL_pending(this->session))
|
||||
sckClientReadWait(this->socket);
|
||||
sckSessionReadWait(this->socketSession);
|
||||
|
||||
// Read and handle errors
|
||||
result = SSL_read(this->session, bufRemainsPtr(buffer), (int)bufRemains(buffer));
|
||||
@@ -391,7 +392,7 @@ tlsWriteContinue(TlsClient *this, int writeResult, int writeError, size_t writeS
|
||||
THROW_FMT(FileWriteError, "unable to write to tls [%d]", writeError);
|
||||
|
||||
// Wait for the socket to be readable for tls renegotiation
|
||||
sckClientReadWait(this->socket);
|
||||
sckSessionReadWait(this->socketSession);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -447,7 +448,11 @@ tlsClientClose(TlsClient *this)
|
||||
ASSERT(this != NULL);
|
||||
|
||||
// Close the socket
|
||||
sckClientClose(this->socket);
|
||||
if (this->socketSession != NULL)
|
||||
{
|
||||
sckSessionFree(this->socketSession);
|
||||
this->socketSession = NULL;
|
||||
}
|
||||
|
||||
// Free the TLS session
|
||||
if (this->session != NULL)
|
||||
@@ -512,16 +517,20 @@ tlsClientOpen(TlsClient *this)
|
||||
TRY_BEGIN()
|
||||
{
|
||||
// Open the socket
|
||||
sckClientOpen(this->socket);
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
this->socketSession = sckClientOpen(this->socketClient);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
// Negotiate TLS
|
||||
cryptoError((this->session = SSL_new(this->context)) == NULL, "unable to create TLS context");
|
||||
|
||||
cryptoError(
|
||||
SSL_set_tlsext_host_name(this->session, strPtr(sckClientHost(this->socket))) != 1,
|
||||
SSL_set_tlsext_host_name(this->session, strPtr(sckSessionHost(this->socketSession))) != 1,
|
||||
"unable to set TLS host name");
|
||||
cryptoError(
|
||||
SSL_set_fd(this->session, sckClientFd(this->socket)) != 1, "unable to add socket to TLS context");
|
||||
SSL_set_fd(this->session, sckSessionFd(this->socketSession)) != 1, "unable to add socket to TLS context");
|
||||
cryptoError(SSL_connect(this->session) != 1, "unable to negotiate TLS connection");
|
||||
|
||||
// Connection was successful
|
||||
@@ -559,13 +568,13 @@ tlsClientOpen(TlsClient *this)
|
||||
{
|
||||
THROW_FMT(
|
||||
CryptoError, "unable to verify certificate presented by '%s:%u': [%ld] %s",
|
||||
strPtr(sckClientHost(this->socket)), sckClientPort(this->socket), verifyResult,
|
||||
strPtr(sckSessionHost(this->socketSession)), sckSessionPort(this->socketSession), verifyResult,
|
||||
X509_verify_cert_error_string(verifyResult));
|
||||
}
|
||||
|
||||
// Verify that the hostname appears in the certificate
|
||||
X509 *certificate = SSL_get_peer_certificate(this->session);
|
||||
bool nameResult = tlsClientHostVerify(sckClientHost(this->socket), certificate);
|
||||
bool nameResult = tlsClientHostVerify(sckSessionHost(this->socketSession), certificate);
|
||||
X509_free(certificate);
|
||||
|
||||
if (!nameResult)
|
||||
@@ -573,7 +582,7 @@ tlsClientOpen(TlsClient *this)
|
||||
THROW_FMT(
|
||||
CryptoError,
|
||||
"unable to find hostname '%s' in certificate common name or subject alternative names",
|
||||
strPtr(sckClientHost(this->socket)));
|
||||
strPtr(sckSessionHost(this->socketSession)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -246,6 +246,7 @@ unit:
|
||||
common/io/tls/client: full
|
||||
common/io/socket/client: full
|
||||
common/io/socket/common: full
|
||||
common/io/socket/session: full
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: io-http
|
||||
|
||||
Reference in New Issue
Block a user