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

Fixed memory leak caused by SSL debug function. #59

Merged
merged 5 commits into from
Mar 15, 2024
Merged
Changes from all 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
123 changes: 65 additions & 58 deletions c/src/point_one/polaris/polaris.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,45 +23,56 @@
#define STR(x) MAKE_STR(x)

#if defined(P1_NO_PRINT)
# define P1_Print(x, ...) do {} while(0)
# define P1_PrintError(x, ...) do {} while(0)
# define P1_DebugPrint(x, ...) do {} while(0)
# define PrintData(buffer, length) do {} while(0)
# if defined(POLARIS_USE_TLS)
# define ShowCerts(ssl) do {} while(0)
# endif
#define P1_Print(x, ...) \
do { \
} while (0)
#define P1_PrintError(x, ...) \
do { \
} while (0)
#define P1_DebugPrint(x, ...) \
do { \
} while (0)
#define PrintData(buffer, length) \
do { \
} while (0)
#if defined(POLARIS_USE_TLS)
#define ShowCerts(ssl) \
do { \
} while (0)
#endif
#else
static int __log_level = POLARIS_LOG_LEVEL_INFO;

# define P1_Print(x, ...) \
#define P1_Print(x, ...) \
P1_fprintf(stderr, "polaris.c:" STR(__LINE__) "] " x, ##__VA_ARGS__)
# define P1_PrintError(x, ...) \
#define P1_PrintError(x, ...) \
P1_perror("polaris.c:" STR(__LINE__) "] " x, ##__VA_ARGS__)
# define P1_DebugPrint(x, ...) \
if (__log_level >= POLARIS_LOG_LEVEL_DEBUG) { \
P1_Print(x, ##__VA_ARGS__); \
#define P1_DebugPrint(x, ...) \
if (__log_level >= POLARIS_LOG_LEVEL_DEBUG) { \
P1_Print(x, ##__VA_ARGS__); \
}
# define P1_TracePrint(x, ...) \
if (__log_level >= POLARIS_LOG_LEVEL_TRACE) { \
P1_Print(x, ##__VA_ARGS__); \
#define P1_TracePrint(x, ...) \
if (__log_level >= POLARIS_LOG_LEVEL_TRACE) { \
P1_Print(x, ##__VA_ARGS__); \
}

static void P1_PrintData(const uint8_t* buffer, size_t length);
# if defined(POLARIS_USE_TLS)
#if defined(POLARIS_USE_TLS)
static void ShowCerts(SSL* ssl);
# endif
#endif
#endif

#if defined(POLARIS_NO_PRINT)
# define P1_PrintReadWriteError(context, x, ret) do {} while(0)
#define P1_PrintReadWriteError(context, x, ret) \
do { \
} while (0)
#elif defined(POLARIS_USE_TLS)
static void __P1_PrintReadWriteError(int line, PolarisContext_t* context,
const char* message, int ret) {
SSL_load_error_strings();
int ssl_error = SSL_get_error(context->ssl, ret);
if (ssl_error == SSL_ERROR_SYSCALL) {
P1_fprintf(stderr,
"polaris.c:%d] %s. [error=%s (syscall: errno=%d; %s)]\n",
P1_fprintf(stderr, "polaris.c:%d] %s. [error=%s (syscall: errno=%d; %s)]\n",
line, message, strerror(errno), errno,
ERR_error_string(ssl_error, NULL));
} else {
Expand Down Expand Up @@ -107,10 +118,10 @@ static void __P1_PrintReadWriteError(int line, PolarisContext_t* context,
}
}

# define P1_PrintReadWriteError(context, x, ret) \
#define P1_PrintReadWriteError(context, x, ret) \
__P1_PrintReadWriteError(__LINE__, context, x, ret)
#else
# define P1_PrintReadWriteError(context, x, ret) P1_PrintError(x, ret)
#define P1_PrintReadWriteError(context, x, ret) P1_PrintError(x, ret)
#endif

#define P1_DebugPrintReadWriteError(context, x, ret) \
Expand Down Expand Up @@ -163,9 +174,7 @@ int Polaris_Init(PolarisContext_t* context) {
}

/******************************************************************************/
void Polaris_Free(PolarisContext_t* context) {
CloseSocket(context, 1);
}
void Polaris_Free(PolarisContext_t* context) { CloseSocket(context, 1); }

/******************************************************************************/
void Polaris_SetLogLevel(int log_level) {
Expand Down Expand Up @@ -216,17 +225,16 @@ int Polaris_AuthenticateTo(PolarisContext_t* context, const char* api_key,
return POLARIS_NOT_ENOUGH_SPACE;
}

P1_DebugPrint("Sending auth request. [api_key=%s, unique_id=%s, url=%s]\n",
api_key, unique_id, api_url);
P1_DebugPrint(
"Sending auth request. [api_key=%.7s..., unique_id=%s, url=%s]\n",
api_key, unique_id, api_url);
context->auth_token[0] = '\0';
#ifdef POLARIS_USE_TLS
int status_code =
SendPOSTRequest(context, api_url, 443, "/api/v1/auth/token",
context->recv_buffer, (size_t)content_size);
int status_code = SendPOSTRequest(context, api_url, 443, "/api/v1/auth/token",
context->recv_buffer, (size_t)content_size);
#else
int status_code =
SendPOSTRequest(context, api_url, 80, "/api/v1/auth/token",
context->recv_buffer, (size_t)content_size);
int status_code = SendPOSTRequest(context, api_url, 80, "/api/v1/auth/token",
context->recv_buffer, (size_t)content_size);
#endif
if (status_code < 0) {
P1_Print("Error sending authentication request.\n");
Expand Down Expand Up @@ -318,7 +326,7 @@ int Polaris_ConnectTo(PolarisContext_t* context, const char* endpoint_url,
size_t message_size = Polaris_PopulateChecksum(context->recv_buffer);

P1_DebugPrint("Sending access token message. [size=%u B]\n",
(unsigned)message_size);
(unsigned)message_size);
#ifdef POLARIS_USE_TLS
ret = SSL_write(context->ssl, context->recv_buffer, message_size);
#else
Expand Down Expand Up @@ -401,8 +409,7 @@ void Polaris_Disconnect(PolarisContext_t* context) {

/******************************************************************************/
void Polaris_SetRTCMCallback(PolarisContext_t* context,
PolarisCallback_t callback,
void* callback_info) {
PolarisCallback_t callback, void* callback_info) {
context->rtcm_callback = callback;
context->rtcm_callback_info = callback_info;
}
Expand Down Expand Up @@ -507,7 +514,7 @@ int Polaris_RequestBeacon(PolarisContext_t* context, const char* beacon_id) {
size_t message_size = Polaris_PopulateChecksum(context->send_buffer);

P1_DebugPrint("Sending beacon request. [size=%u B, beacon='%s']\n",
(unsigned)message_size, beacon_id);
(unsigned)message_size, beacon_id);
P1_PrintData(context->send_buffer, message_size);

#ifdef POLARIS_USE_TLS
Expand Down Expand Up @@ -745,8 +752,7 @@ static inline int P1_SetAddress(const char* hostname, int port,
uint32_t ip = FreeRTOS_gethostbyname(hostname);
if (ip == 0) {
return -1;
}
else {
} else {
result->sin_family = AF_INET;
result->sin_port = FreeRTOS_htons(port);
result->sin_addr = ip;
Expand All @@ -760,8 +766,7 @@ static inline int P1_SetAddress(const char* hostname, int port,
if (host_info == NULL) {
P1_Print("Unable to resolve \"%s\": %s\n", hostname, hstrerror(h_errno));
return -1;
}
else {
} else {
result->sin_family = AF_INET;
result->sin_port = htons(port);
memcpy(&result->sin_addr, host_info->h_addr_list[0], host_info->h_length);
Expand Down Expand Up @@ -814,9 +819,11 @@ static int OpenSocket(PolarisContext_t* context, const char* endpoint_url,
// Set send/receive timeouts.
P1_TimeValue_t timeout;
P1_SetTimeMS(POLARIS_RECV_TIMEOUT_MS, &timeout);
setsockopt(context->socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
setsockopt(context->socket, SOL_SOCKET, SO_RCVTIMEO, &timeout,
sizeof(timeout));
P1_SetTimeMS(POLARIS_SEND_TIMEOUT_MS, &timeout);
setsockopt(context->socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
setsockopt(context->socket, SOL_SOCKET, SO_SNDTIMEO, &timeout,
sizeof(timeout));

// Lookup the IP of the endpoint used for auth requests.
P1_SocketAddrV4_t address;
Expand Down Expand Up @@ -1005,9 +1012,9 @@ static int GetHTTPResponse(PolarisContext_t* context) {
int bytes_read;

#ifdef POLARIS_USE_TLS
while ((bytes_read = SSL_read(context->ssl, context->recv_buffer + total_bytes,
POLARIS_RECV_BUFFER_SIZE - total_bytes - 1)) >
0) {
while (
(bytes_read = SSL_read(context->ssl, context->recv_buffer + total_bytes,
POLARIS_RECV_BUFFER_SIZE - total_bytes - 1)) > 0) {
#else
while ((bytes_read = recv(context->socket, context->recv_buffer + total_bytes,
POLARIS_RECV_BUFFER_SIZE - total_bytes - 1, 0)) >
Expand All @@ -1031,18 +1038,18 @@ static int GetHTTPResponse(PolarisContext_t* context) {
// Similarly, FreeRTOS returns -pdFREERTOS_ERRNO_ENOTCONN on an orderly socket
// shutdown rather than 0. Any other <0 return is considered an error.
else if (bytes_read != -pdFREERTOS_ERRNO_ENOTCONN) {
P1_PrintReadWriteError(
context, "Unexpected error while waiting for HTTP response",
bytes_read);
P1_PrintReadWriteError(context,
"Unexpected error while waiting for HTTP response",
bytes_read);
return POLARIS_SEND_ERROR;
}
#else
// Check for socket read errors. Under normal circumstances, recv() should
// return 0 when finished, indicating the HTTP server closed the connection.
if (bytes_read < 0) {
P1_PrintReadWriteError(
context, "Unexpected error while waiting for HTTP response",
bytes_read);
P1_PrintReadWriteError(context,
"Unexpected error while waiting for HTTP response",
bytes_read);
return POLARIS_SEND_ERROR;
}
#endif
Expand Down Expand Up @@ -1102,18 +1109,18 @@ void P1_PrintData(const uint8_t* buffer, size_t length) {
/******************************************************************************/
#if !defined(P1_NO_PRINT) && defined(POLARIS_USE_TLS)
void ShowCerts(SSL* ssl) {
if (__log_level >= POLARIS_LOG_LEVEL_DEBUG) {
if (__log_level < POLARIS_LOG_LEVEL_DEBUG) {
return;
}

X509* cert = SSL_get_peer_certificate(ssl);
if (cert != NULL) {
char* line;
char line[256];
P1_DebugPrint("Server certificates:\n");
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
P1_DebugPrint("Subject: %s\n", line);
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
P1_DebugPrint("Issuer: %s\n", line);
X509_NAME_oneline(X509_get_subject_name(cert), line, sizeof(line));
P1_DebugPrint(" Subject: %s\n", line);
X509_NAME_oneline(X509_get_issuer_name(cert), line, sizeof(line));
P1_DebugPrint(" Issuer: %s\n", line);
} else {
P1_DebugPrint("No client certificates configured.\n");
}
Expand Down
Loading