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

add function to get local address name #397

Merged
merged 20 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
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
4 changes: 3 additions & 1 deletion common/reals/real_socket_transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
socket_transport_send, \
socket_transport_receive, \
socket_transport_get_underlying_socket, \
socket_transport_is_valid_socket \
socket_transport_is_valid_socket, \
socket_transport_get_local_address \
)

#ifdef __cplusplus
Expand All @@ -42,6 +43,7 @@ SOCKET_SEND_RESULT real_socket_transport_send(SOCKET_TRANSPORT_HANDLE socket_tra
SOCKET_RECEIVE_RESULT real_socket_transport_receive(SOCKET_TRANSPORT_HANDLE socket_transport, SOCKET_BUFFER* payload, uint32_t buffer_count, uint32_t* bytes_recv, uint32_t flags, void* data);
SOCKET_HANDLE real_socket_transport_get_underlying_socket(SOCKET_TRANSPORT_HANDLE socket_transport);
bool real_socket_transport_is_valid_socket(SOCKET_TRANSPORT_HANDLE socket_transport_handle);
int real_socket_transport_get_local_address(SOCKET_TRANSPORT_HANDLE socket_transport, char hostname[MAX_GET_HOST_NAME_LEN], LOCAL_ADDRESS** local_address_list, uint32_t* address_count);

#ifdef __cplusplus
}
Expand Down
4 changes: 3 additions & 1 deletion common/reals/real_socket_transport_renames.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
#define socket_transport_receive real_socket_transport_receive
#define socket_transport_get_underlying_socket real_socket_transport_get_underlying_socket
#define socket_transport_is_valid_socket real_socket_transport_is_valid_socket
#define socket_transport_get_local_address real_socket_transport_get_local_address

#define SOCKET_SEND_RESULT real_SOCKET_SEND_RESULT
#define SOCKET_RECEIVE_RESULT real_SOCKET_RECEIVE_RESULT
#define SOCKET_ACCEPT_RESULT real_SOCKET_ACCEPT_RESULT
#define SOCKET_TYPE real_SOCKET_TYPE
#define SOCKET_IO_TYPE real_SOCKET_IO_TYPE
#define SOCKET_IO_TYPE real_SOCKET_IO_TYPE
#define ADDRESS_TYPE real_ADDRESS_TYPE
17 changes: 16 additions & 1 deletion interfaces/devdoc/socket_transport_requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ typedef struct SOCKET_BUFFER_TAG
void* buffer;
} SOCKET_BUFFER;

typedef struct LOCAL_ADDRESS_TAG
{
ADDRESS_TYPE address_type;
char address[MAX_LOCAL_ADDRESS_LEN];
} LOCAL_ADDRESS;

MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_client);
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_server);
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_from_socket, SOCKET_HANDLE, socket_handle);
Expand All @@ -74,6 +80,7 @@ MOCKABLE_FUNCTION(, SOCKET_RECEIVE_RESULT, socket_transport_receive, SOCKET_TRAN

MOCKABLE_FUNCTION(, SOCKET_HANDLE, socket_transport_get_underlying_socket, SOCKET_TRANSPORT_HANDLE, socket_transport);
MOCKABLE_FUNCTION(, bool, socket_transport_is_valid_socket, SOCKET_TRANSPORT_HANDLE, socket_transport_handle);
MOCKABLE_FUNCTION(, int, socket_transport_get_local_address, SOCKET_TRANSPORT_HANDLE, socket_transport, char, hostname[MAX_GET_HOST_NAME_LEN], LOCAL_ADDRESS**, local_address_list, uint32_t*, address_count);
```

### socket_transport_create_client
Expand Down Expand Up @@ -171,4 +178,12 @@ MOCKABLE_FUNCTION(, SOCKET_HANDLE, socket_transport_get_underlying_socket, SOCKE
MOCKABLE_FUNCTION(, bool, socket_transport_is_valid_socket, SOCKET_TRANSPORT_HANDLE, socket_transport_handle);
```

`socket_transport_check_valid_handle` checks that the internal socket is valid.
`socket_transport_check_valid_handle` checks that the internal socket is valid.

### socket_transport_get_local_address

```c
MOCKABLE_FUNCTION(, int, socket_transport_get_local_address, SOCKET_TRANSPORT_HANDLE, socket_transport, char, hostname[MAX_GET_HOST_NAME_LEN], LOCAL_ADDRESS**, local_address_list, uint32_t*, address_count);
```

`socket_transport_get_local_address` shall return the hostname and IP addresses of the local machine.
17 changes: 17 additions & 0 deletions interfaces/inc/c_pal/socket_transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ extern "C" {
#include "socket_handle.h"


#define MAX_GET_HOST_NAME_LEN 256
#define MAX_LOCAL_ADDRESS_LEN 22

typedef struct SOCKET_TRANSPORT_TAG* SOCKET_TRANSPORT_HANDLE;

#define SOCKET_SEND_RESULT_VALUES \
Expand Down Expand Up @@ -50,6 +53,13 @@ MU_DEFINE_ENUM(SOCKET_ACCEPT_RESULT, SOCKET_ACCEPT_RESULT_VALUES)

MU_DEFINE_ENUM(SOCKET_TYPE, SOCKET_TYPE_VALUES)

#define ADDRESS_TYPE_VALUES \
ADDRESS_INET, \
ADDRESS_INET_6, \
ADDRESS_NETBIOS

MU_DEFINE_ENUM(ADDRESS_TYPE, ADDRESS_TYPE_VALUES)

typedef struct SOCKET_BUFFER_TAG
{
uint32_t length;
Expand All @@ -61,6 +71,12 @@ typedef struct SOCKET_BUFFER_TAG
extern "C" {
#endif

typedef struct LOCAL_ADDRESS_TAG
{
ADDRESS_TYPE address_type;
char address[MAX_LOCAL_ADDRESS_LEN];
} LOCAL_ADDRESS;

MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_client);
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_server);
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_from_socket, SOCKET_HANDLE, socket_handle);
Expand All @@ -77,6 +93,7 @@ MOCKABLE_FUNCTION(, SOCKET_RECEIVE_RESULT, socket_transport_receive, SOCKET_TRAN

MOCKABLE_FUNCTION(, SOCKET_HANDLE, socket_transport_get_underlying_socket, SOCKET_TRANSPORT_HANDLE, socket_transport);
MOCKABLE_FUNCTION(, bool, socket_transport_is_valid_socket, SOCKET_TRANSPORT_HANDLE, socket_transport_handle);
MOCKABLE_FUNCTION(, int, socket_transport_get_local_address, SOCKET_TRANSPORT_HANDLE, socket_transport, char, hostname[MAX_GET_HOST_NAME_LEN], LOCAL_ADDRESS**, local_address_list, uint32_t*, address_count);

#ifdef __cplusplus
}
Expand Down
65 changes: 62 additions & 3 deletions interfaces/tests/socket_transport_int/socket_transport_int.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@
#include <string.h>

#include "testrunnerswitcher.h"
#include "c_pal/threadapi.h"
#include "c_pal/interlocked.h"

#include "macro_utils/macro_utils.h" // IWYU pragma: keep

#include "c_logging/logger.h" // IWYU pragma: keep

#include "c_pal/platform.h" // IWYU pragma: keep
#include "c_pal/gballoc_hl.h"
#include "c_pal/gballoc_hl_redirect.h" // IWYU pragma: keep
#include "c_pal/platform.h" // IWYU pragma: keep
#include "c_pal/threadapi.h"
#include "c_pal/interlocked.h"
#include "c_pal/socket_transport.h"
#include "c_pal/timer.h" // IWYU pragma: keep

Expand Down Expand Up @@ -48,6 +49,8 @@ TEST_DEFINE_ENUM_TYPE(SOCKET_SEND_RESULT, SOCKET_SEND_RESULT_VALUES);
TEST_DEFINE_ENUM_TYPE(SOCKET_RECEIVE_RESULT, SOCKET_RECEIVE_RESULT_VALUES);
TEST_DEFINE_ENUM_TYPE(SOCKET_ACCEPT_RESULT, SOCKET_ACCEPT_RESULT_VALUES);
TEST_DEFINE_ENUM_TYPE(THREADAPI_RESULT, THREADAPI_RESULT_VALUES);
TEST_DEFINE_ENUM_TYPE(SOCKET_TYPE, SOCKET_TYPE_VALUES);
TEST_DEFINE_ENUM_TYPE(ADDRESS_TYPE, ADDRESS_TYPE_VALUES);

BEGIN_TEST_SUITE(TEST_SUITE_NAME_FROM_CMAKE)

Expand All @@ -66,6 +69,7 @@ TEST_SUITE_CLEANUP(suite_cleanup)

TEST_FUNCTION_INITIALIZE(method_init)
{
g_port_num++;
}

TEST_FUNCTION_CLEANUP(method_cleanup)
Expand Down Expand Up @@ -416,4 +420,59 @@ TEST_FUNCTION(socket_transport_chaos_knight_test)

}

TEST_FUNCTION(get_local_socket_address_test)
{
// assert
SOCKET_TRANSPORT_HANDLE listen_socket = socket_transport_create_server();
ASSERT_IS_NOT_NULL(listen_socket);

ASSERT_ARE_EQUAL(int, 0, socket_transport_listen(listen_socket, g_port_num));

// create the async socket object
SOCKET_TRANSPORT_HANDLE client_socket = socket_transport_create_client();
ASSERT_IS_NOT_NULL(client_socket);

ASSERT_ARE_EQUAL(int, 0, socket_transport_connect(client_socket, "localhost", g_port_num, TEST_CONN_TIMEOUT));

SOCKET_TRANSPORT_HANDLE incoming_socket;
ASSERT_ARE_EQUAL(SOCKET_ACCEPT_RESULT, SOCKET_ACCEPT_OK, socket_transport_accept(listen_socket, &incoming_socket, TEST_CONN_TIMEOUT));
ASSERT_IS_NOT_NULL(incoming_socket);

char client_hostname[MAX_GET_HOST_NAME_LEN] = { 0 };
char server_hostname[MAX_GET_HOST_NAME_LEN] = { 0 };

LOCAL_ADDRESS* server_local_address_list;
LOCAL_ADDRESS* client_local_address_list;
uint32_t server_list_count;
uint32_t client_list_count;
ASSERT_ARE_EQUAL(int, 0, socket_transport_get_local_address(incoming_socket, server_hostname, &server_local_address_list, &server_list_count));
ASSERT_ARE_EQUAL(int, 0, socket_transport_get_local_address(client_socket, client_hostname, &client_local_address_list, &client_list_count));

LogVerbose("Client Address:");
for (uint32_t index = 0; index < client_list_count; index++)
{
LogVerbose("\tType: %" PRI_MU_ENUM ", Address: %s", MU_ENUM_VALUE(ADDRESS_TYPE, client_local_address_list[0].address_type), client_local_address_list[0].address);
}
LogVerbose("Incoming Address:");
for (uint32_t index = 0; index < server_list_count; index++)
{
LogVerbose("\tType: %" PRI_MU_ENUM ", Address: %s", MU_ENUM_VALUE(ADDRESS_TYPE, server_local_address_list[0].address_type), server_local_address_list[0].address);
}

ASSERT_ARE_EQUAL(char_ptr, server_hostname, client_hostname);
ASSERT_ARE_EQUAL(uint32_t, server_list_count, client_list_count);

socket_transport_disconnect(client_socket);
socket_transport_destroy(client_socket);

socket_transport_disconnect(incoming_socket);
socket_transport_destroy(incoming_socket);

socket_transport_disconnect(listen_socket);
socket_transport_destroy(listen_socket);

free(server_local_address_list);
free(client_local_address_list);
}

END_TEST_SUITE(TEST_SUITE_NAME_FROM_CMAKE)
33 changes: 32 additions & 1 deletion linux/devdoc/socket_transport_linux_requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ MOCKABLE_FUNCTION(, SOCKET_RECEIVE_RESULT, socket_transport_receive, SOCKET_TRAN

MOCKABLE_FUNCTION(, SOCKET_HANDLE, socket_transport_get_underlying_socket, SOCKET_TRANSPORT_HANDLE, socket_transport);
MOCKABLE_FUNCTION(, bool, socket_transport_is_valid_socket, SOCKET_TRANSPORT_HANDLE, socket_transport_handle);
MOCKABLE_FUNCTION(, int, socket_transport_get_local_address, SOCKET_TRANSPORT_HANDLE, socket_transport, char, hostname[MAX_GET_HOST_NAME_LEN], LOCAL_ADDRESS**, local_address_list, uint32_t*, address_count);
```

### socket_transport_create_client
Expand Down Expand Up @@ -344,4 +345,34 @@ MOCKABLE_FUNCTION(, bool, socket_transport_is_valid_socket, SOCKET_TRANSPORT_HAN

**SOCKET_TRANSPORT_LINUX_11_094: [** If the socket inside `socket_transport_handle` is an `INVALID_SOCKET`, `socket_transport_is_valid_socket` shall fail and return `false`. **]**

**SOCKET_TRANSPORT_LINUX_11_095: [** On success, `socket_transport_is_valid_socket` shall return `true`. **]**
**SOCKET_TRANSPORT_LINUX_11_095: [** On success, `socket_transport_is_valid_socket` shall return `true`. **]**

### socket_transport_get_local_address

```c
MOCKABLE_FUNCTION(, int, socket_transport_get_local_address, SOCKET_TRANSPORT_HANDLE, socket_transport, char, hostname[MAX_GET_HOST_NAME_LEN], LOCAL_ADDRESS**, local_address_list, uint32_t*, address_count);
```

`socket_transport_get_local_address` gets the interface addresses and hostname of the current machine.

**SOCKET_TRANSPORT_LINUX_11_098: [** If `socket_transport` is `NULL`, `socket_transport_get_local_address` shall fail and return a non-zero value. **]**

**SOCKET_TRANSPORT_LINUX_11_099: [** If `hostname` is `NULL`, `socket_transport_get_local_address` shall fail and return a non-zero value. **]**

**SOCKET_TRANSPORT_LINUX_11_100: [** If `local_address_list` is not `NULL` and `address_count` is `NULL`, `socket_transport_get_local_address` shall fail and return a non-zero value. **]**

**SOCKET_TRANSPORT_LINUX_11_101: [** `socket_transport_get_local_address` shall call `sm_exec_begin`. **]**

**SOCKET_TRANSPORT_LINUX_11_102: [** `socket_transport_get_local_address` shall get the `hostname` by calling `gethostname`. **]**

**SOCKET_TRANSPORT_LINUX_11_103: [** If `local_address_list` is not `NULL`, `socket_transport_get_local_address` shall call `getifaddrs` to get the link list of ifaddrs. **]**

**SOCKET_TRANSPORT_LINUX_11_104: [** `socket_transport_get_local_address` shall allocate the `LOCAL_ADDRESS` array for each ifaddrs with a `sa_family` of `AF_INET` and the interface is up and running. **]**

**SOCKET_TRANSPORT_LINUX_11_105: [** For each IP in the `ifaddr` object if the `sa_family` is `AF_INET` and the interface is up and running and it's not a loopback, `socket_transport_get_local_address` shall retrieve the name of the address by calling `getnameinfo`. **]**

**SOCKET_TRANSPORT_LINUX_11_106: [** `socket_transport_get_local_address` shall call `sm_exec_end`. **]**

**SOCKET_TRANSPORT_LINUX_11_107: [** On success `socket_transport_get_local_address` shall return 0. **]**

**SOCKET_TRANSPORT_LINUX_11_108: [** If any failure is encountered, `socket_transport_get_local_address` shall fail and return a non-zero value. **]**
Loading