*/
int vine_dp_set_remote_ip(vine_dp_h dp, vine_address_family_e addr_family, const char *ip);
+/**
+ * @brief Gets the remote IP address.
+ * @remarks @a ip must be released using free().
+ * @since_tizen 6.5
+ * @param[in] dp The data path handle
+ * @param[out] addr_family The address family
+ * @param[out] ip The remote IP address
+ * @return 0 on success, otherwise a negative error value
+ * @retval #VINE_ERROR_NONE Successful
+ * @retval #VINE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #VINE_ERROR_NOT_SUPPORTED Not supported
+ * @see vine_dp_create()
+ */
+int vine_dp_get_remote_ip(vine_dp_h dp, vine_address_family_e *addr_family, char **ip);
+
/**
* @brief Sets the port.
* @remarks @a port is a remote server port if @a dp's type is VINE_DP_TYPE_CLIENT. \
%bcond_without lws_static_prebuilt
Name: capi-network-vine
Summary: An service discovery framework
-Version: 1.0.0
+Version: 1.0.1
Release: 0
Group: Network & Connectivity/API
License: Apache-2.0
VINE_LOGD("[libwebsockets:%d] %s", level, line);
}
-static void _get_peer_network_info(struct lws *wsi, char ip[], int *port)
+#define IPV4_MAPPED_IPV6_PREFIX "::ffff:"
+#define IPV4_MAPPED_IPv6_PREFIX_LEN 7
+
+static bool __is_ipv4_mapped(const char *ip)
+{
+ return strncmp(IPV4_MAPPED_IPV6_PREFIX, ip, IPV4_MAPPED_IPv6_PREFIX_LEN) == 0;
+}
+
+static void _get_peer_network_info(struct lws *wsi,
+ vine_dp_addr_family_e *family, char ip[], int *port)
{
struct sockaddr_storage addr;
socklen_t len = sizeof(addr);
if (addr.ss_family == AF_INET) {
struct sockaddr_in *s = (struct sockaddr_in*)&addr;
*port = ntohs(s->sin_port);
+ *family = VINE_DP_IPV4;
inet_ntop(AF_INET, &s->sin_addr, ip, INET6_ADDRSTRLEN);
} else {
struct sockaddr_in6 *s = (struct sockaddr_in6*)&addr;
*port = ntohs(s->sin6_port);
inet_ntop(AF_INET6, &s->sin6_addr, ip, INET6_ADDRSTRLEN);
+ if (__is_ipv4_mapped(ip)) {
+ int ip_len = strlen(ip) - IPV4_MAPPED_IPv6_PREFIX_LEN;
+ strncpy(ip, ip + IPV4_MAPPED_IPv6_PREFIX_LEN, ip_len);
+ ip[ip_len] = 0;
+ *family = VINE_DP_IPV4;
+ }
+ else {
+ *family = VINE_DP_IPV6;
+ }
}
VINE_LOGD("address family[%d] peer ip[%s], peer port[%d]\n", addr.ss_family, ip, *port);
websocket_s *client_ws = (websocket_s *)lws_wsi_user(wsi);
vhd->curr_conn++;
if (g_callbacks.accepted_cb) {
+ vine_dp_addr_family_e addr_family;
char ip[INET6_ADDRSTRLEN];
int port;
- _get_peer_network_info(wsi, ip, &port);
- g_callbacks.accepted_cb(ip, port, client_ws, vhd->user);
+ _get_peer_network_info(wsi, &addr_family, ip, &port);
+ g_callbacks.accepted_cb(addr_family, ip, port, client_ws, vhd->user);
}
break;
}
typedef struct {
void (*pollfd_cb)(vine_data_path_pollfd_op_e op, int fd, int event);
void (*opened_cb)(int result, int port, void *user_data);
- void (*accepted_cb)(char *addr, int port, void *plugin_data, void *user_data);
+ void (*accepted_cb)(vine_dp_addr_family_e addr_family, char *addr, int port, void *plugin_data, void *user_data);
void (*connected_cb)(int result, void *user_data);
void (*received_cb)(size_t bytes, void *user);
void (*written_cb)(int bytes, void *user_data);
int _vine_data_path_destroy(vine_data_path_h datapath);
const char *_vine_data_path_get_ip(vine_data_path_h datapath);
+vine_address_family_e _vine_data_path_get_addr_family(vine_data_path_h datapath);
int _vine_data_path_get_port(vine_data_path_h datapath);
int vine_data_path_init(void);
virtual int set_addr_family(vine_address_family_e addr_family) = 0;
virtual int set_remote_ip(vine_address_family_e, const std::string &ip) = 0;
+ virtual int get_remote_ip(vine_address_family_e *addr_family, char **ip) = 0;
virtual int set_port(int port) = 0;
virtual int get_port() = 0;
virtual int set_topic(std::string topic) = 0;
virtual int set_addr_family(vine_address_family_e addr_family);
virtual int set_remote_ip(vine_address_family_e, const std::string &ip);
+ virtual int get_remote_ip(vine_address_family_e *addr_family, char **ip);
virtual int set_port(int port);
virtual int get_port(){ return mListenPort; };
virtual int set_topic(std::string topic);
virtual int set_addr_family(vine_address_family_e addr_family);
virtual int set_remote_ip(vine_address_family_e, const std::string &ip);
+ virtual int get_remote_ip(vine_address_family_e *addr_family, char **ip);
virtual int set_port(int port);
- virtual int get_port(){ return mServerPort; };
+ virtual int get_port(){ return mPeerPort; };
virtual int set_topic(std::string topic);
virtual int set_max_connections(int max_conn){ return VINE_ERROR_NONE; };
virtual int set_accepted_cb(vine_dp_accepted_cb callback, void *user_data);
private:
vine_data_path_h mDataPath;
vine_address_family_e mAddrFamily;
- std::string mServerIp;
- int mServerPort;
+ std::string mPeerIp;
+ int mPeerPort;
+
+ bool isCreatedByServerDp;
};
typedef std::map<std::string, vine_data_path_h> DPMap;
virtual int set_addr_family(vine_address_family_e addr_family);
virtual int set_remote_ip(vine_address_family_e, const std::string &ip);
+ virtual int get_remote_ip(vine_address_family_e *addr_family, char **ip);
virtual int set_port(int port);
virtual int get_port(){ return mListenPort; };
int _vine_dp_set_iface_name(vine_dp_h dp, const char *iface_name);
int _vine_dp_set_addr_family(vine_dp_h dp, vine_address_family_e addr_family);
int _vine_dp_set_remote_ip(vine_dp_h dp, vine_address_family_e addr_family, const char *ip);
+int _vine_dp_get_remote_ip(vine_dp_h dp, vine_address_family_e *addr_family, char **ip);
int _vine_dp_set_port(vine_dp_h dp, int port);
int _vine_dp_get_port(vine_dp_h dp, int *port);
int _vine_dp_set_topic(vine_dp_h dp, const char *topic);
typedef struct {
vine_data_path_type_e type;
+ vine_address_family_e addr_family;
char *addr;
int port;
vine_security_h security;
static void (*__init_plugin)(vine_dp_plugin_fn *fn);
static vine_data_path_s *_vine_data_path_create(vine_data_path_type_e type,
vine_security_h security,
- const char *addr, int port, void *plugin_data, vine_event_queue_h event_fd);
+ vine_address_family_e addr_family, const char *addr,
+ int port, void *plugin_data, vine_event_queue_h event_fd);
static vine_error_e __convert_data_path_error_to_vine_error(vine_data_path_error error)
{
__invoke_opened_user_cb, free, dp);
}
-static void __accepted_cb(char *addr, int port, void *plugin_data, void *user_data)
+static vine_address_family_e __convert_addr_family(vine_dp_addr_family_e addr_family)
+{
+ switch (addr_family) {
+ case VINE_DP_IPV4_IPV6:
+ return VINE_ADDRESS_FAMILY_DEFAULT;
+ case VINE_DP_IPV4:
+ return VINE_ADDRESS_FAMILY_IPV4;
+ case VINE_DP_IPV6:
+ return VINE_ADDRESS_FAMILY_IPV6;
+ }
+ return VINE_ADDRESS_FAMILY_DEFAULT;
+}
+static void __accepted_cb(vine_dp_addr_family_e addr_family, char *addr,
+ int port, void *plugin_data, void *user_data)
{
RET_IF(user_data == NULL, "listen_dp is NULL");
vine_data_path_s *listen_dp = (vine_data_path_s *)user_data;
vine_data_path_s *connected_dp = _vine_data_path_create(VINE_DATA_PATH_TYPE_SERVER,
- listen_dp->security, addr, port, plugin_data, listen_dp->event_fd);
+ listen_dp->security, __convert_addr_family(addr_family), addr, port, plugin_data, listen_dp->event_fd);
RET_IF(connected_dp == NULL, "Out of memory");
VINE_LOGD("Accepted dp[%p] addr[%s] port[%d] listen_dp[%p]", connected_dp, addr, port, user_data);
// This function will be called when publish session is started
// or request to connect to a service.
static vine_data_path_s *_vine_data_path_create(vine_data_path_type_e type,
- vine_security_h security,
+ vine_security_h security, vine_address_family_e addr_family,
const char *addr, int port, void *plugin_data, vine_event_queue_h event_fd)
{
RET_VAL_IF(addr == NULL, NULL, "addr is NULL");
RET_VAL_IF(dp == NULL, NULL, "Out of memory");
dp->type = type;
+ dp->addr_family = addr_family;
+
dp->addr = STRDUP(addr);
if (dp->addr == NULL) {
VINE_LOGE("Out of memory");
return (const char *)dp->addr;
}
+vine_address_family_e _vine_data_path_get_addr_family(vine_data_path_h datapath)
+{
+ RET_VAL_IF(datapath == NULL, VINE_ADDRESS_FAMILY_DEFAULT, "datapath is NULL");
+ vine_data_path_s *dp = (vine_data_path_s *)datapath;
+ return dp->addr_family;
+}
+
int _vine_data_path_get_port(vine_data_path_h datapath)
{
RET_VAL_IF(datapath == NULL, VINE_ERROR_INVALID_PARAMETER, "datapath is NULL");
}
vine_data_path_s *dp =
- _vine_data_path_create(VINE_DATA_PATH_TYPE_SERVER, security, "", port, NULL, event_fd);
+ _vine_data_path_create(VINE_DATA_PATH_TYPE_SERVER, security,
+ addr_family, "", port, NULL, event_fd);
RET_VAL_IF(dp == NULL, VINE_ERROR_OUT_OF_MEMORY, "Out of memory");
vine_dp_ssl ssl = {false, VINE_DP_TLS_VERSION_DEFAULT, 0, NULL, NULL, NULL};
vine_data_path_h *connected_datapath, vine_event_queue_h event_fd)
{
vine_data_path_s *dp =
- _vine_data_path_create(VINE_DATA_PATH_TYPE_CLIENT, security, ip, port, NULL, event_fd);
+ _vine_data_path_create(VINE_DATA_PATH_TYPE_CLIENT, security, addr_family, ip, port, NULL, event_fd);
RET_VAL_IF(dp == NULL, VINE_ERROR_OUT_OF_MEMORY, "Out of memory");
RET_VAL_IF(connected_datapath == NULL, VINE_ERROR_INVALID_PARAMETER, "connected_datapath is NULL");
- if (dp->addr)
- free(dp->addr);
- dp->addr = STRDUP(ip);
- dp->port = port;
dp->connected_cb = callback;
dp->connected_cb_data = user_data;
return VINE_ERROR_INVALID_OPERATION;
}
+int DPServer::get_remote_ip(vine_address_family_e *addr_family, char **ip)
+{
+ return VINE_ERROR_INVALID_OPERATION;
+}
+
int DPServer::set_port(int port)
{
if (port < 0 || port > 65535)
mAddrFamily = VINE_ADDRESS_FAMILY_DEFAULT;
mIfaceName = "";
mDataPath = NULL;
- mServerIp = "";
- mServerPort = 0;
+ mPeerIp = "";
+ mPeerPort = 0;
mReceivedCb = NULL;
mReceivedCbData = NULL;
mOpenedCb = NULL;
mOpenedCbData = NULL;
mTerminatedCb = NULL;
mTerminatedCbData = NULL;
+
+ isCreatedByServerDp = false;
}
DPClient::DPClient(void *event_fd, void *datapath)
mSecurity = NULL;
mOpenState = VINE_DP_OPEN_STATE_NONE;
mDataPath = datapath;
- mAddrFamily = VINE_ADDRESS_FAMILY_IPV4;
- mServerIp = "";
- mServerPort = 0;
+ mAddrFamily = _vine_data_path_get_addr_family(mDataPath);
+ mPeerIp = _vine_data_path_get_ip(mDataPath);
+ mPeerPort = _vine_data_path_get_port(mDataPath);
mReceivedCb = NULL;
mReceivedCbData = NULL;
mOpenedCb = NULL;
mOpenedCbData = NULL;
mTerminatedCb = NULL;
mTerminatedCbData = NULL;
+
+ isCreatedByServerDp = true;
}
DPClient::~DPClient()
int DPClient::set_remote_ip(vine_address_family_e addr_family, const std::string &ip)
{
+ RET_VAL_IF(isCreatedByServerDp, VINE_ERROR_INVALID_OPERATION, "cannot set remote IP");
if (!_check_if_valid_ip(addr_family, ip.c_str()))
return VINE_ERROR_INVALID_PARAMETER;
- mServerIp = ip;
+ mPeerIp = ip;
mAddrFamily = addr_family;
return VINE_ERROR_NONE;
}
+int DPClient::get_remote_ip(vine_address_family_e *addr_family, char **ip)
+{
+ *addr_family = mAddrFamily;
+ *ip = STRDUP(mPeerIp.c_str());
+ return VINE_ERROR_NONE;
+}
+
int DPClient::set_port(int port)
{
+ RET_VAL_IF(isCreatedByServerDp, VINE_ERROR_INVALID_OPERATION, "cannot set port");
if (port <= 0 || port > 65535) // Do not allow 0
return VINE_ERROR_INVALID_PARAMETER;
- mServerPort = port;
+ mPeerPort = port;
return VINE_ERROR_NONE;
}
int DPClient::open(vine_dp_opened_cb callback, void *user_data)
{
+ RET_VAL_IF(isCreatedByServerDp, VINE_ERROR_INVALID_OPERATION, "cannot open");
RET_ERR_IF_DP_OPEN_STATE_ISNT_IDLE(mOpenState);
mOpenedCb = callback;
mOpenedCbData = user_data;
mOpenState = VINE_DP_OPEN_STATE_WAIT;
- int ret = vine_data_path_connect(mAddrFamily, mServerIp.c_str(), mServerPort,
+ int ret = vine_data_path_connect(mAddrFamily, mPeerIp.c_str(), mPeerPort,
mIfaceName.size() > 0 ? mIfaceName.c_str() : NULL,
mSecurity, NULL,
_connected_cb, static_cast<void *>(this), &mDataPath, mEventFd);
return VINE_ERROR_INVALID_OPERATION;
}
+int DPPubSub::get_remote_ip(vine_address_family_e *addr_family, char **ip)
+{
+ return VINE_ERROR_INVALID_OPERATION;
+}
+
int DPPubSub::set_port(int port)
{
if (port < 0 || port > 65535)
return _dp->set_remote_ip(addr_family, ip);
}
+int _vine_dp_get_remote_ip(vine_dp_h dp, vine_address_family_e *addr_family, char **ip)
+{
+ RET_VAL_IF(dp == NULL, VINE_ERROR_INVALID_PARAMETER, "dp is null.");
+ RET_VAL_IF(addr_family == NULL, VINE_ERROR_INVALID_PARAMETER, "addr_family is null.");
+ RET_VAL_IF(ip == NULL, VINE_ERROR_INVALID_PARAMETER, "ip is null.");
+
+ DataPath *_dp = static_cast<DataPath *>(dp);
+ return _dp->get_remote_ip(addr_family, ip);
+}
+
int _vine_dp_set_port(vine_dp_h dp, int port)
{
RET_VAL_IF(dp == NULL, VINE_ERROR_INVALID_PARAMETER, "dp is null.");
return _vine_dp_set_remote_ip(dp, addr_family, ip);
}
+API int vine_dp_get_remote_ip(vine_dp_h dp, vine_address_family_e *addr_family, char **ip)
+{
+ __VINE_FUNC_ENTER__;
+ CHECK_FEATURE_SUPPORTED;
+
+ return _vine_dp_get_remote_ip(dp, addr_family, ip);
+}
+
API int vine_dp_set_port(vine_dp_h dp, int port)
{
__VINE_FUNC_ENTER__;
#include "mocks/vine-mock-memory.h"
+#define TEST_IP "192.168.1.123"
+
class VineDpTest : public ::testing::Test {
protected:
vine_dp_h server_dp;
EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER,
vine_dp_set_remote_ip(client_dp, VINE_ADDRESS_FAMILY_IPV4, NULL));
EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER,
- vine_dp_set_remote_ip(NULL, VINE_ADDRESS_FAMILY_IPV4, "192.168.1.123"));
+ vine_dp_set_remote_ip(NULL, VINE_ADDRESS_FAMILY_IPV4, TEST_IP));
EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER,
- vine_dp_set_remote_ip(client_dp, VINE_ADDRESS_FAMILY_IPV6, "192.168.1.123"));
+ vine_dp_set_remote_ip(client_dp, VINE_ADDRESS_FAMILY_IPV6, TEST_IP));
EXPECT_EQ(VINE_ERROR_INVALID_OPERATION,
- vine_dp_set_remote_ip(server_dp, VINE_ADDRESS_FAMILY_IPV4, "192.168.1.123"));
+ vine_dp_set_remote_ip(server_dp, VINE_ADDRESS_FAMILY_IPV4, TEST_IP));
}
-TEST_F(VineDpTest, SetRemoteIpP)
+TEST_F(VineDpTest, GetRemoteN)
{
+ vine_address_family_e family;
+ char *ip;
+ EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER,
+ vine_dp_get_remote_ip(client_dp, NULL, &ip));
+ EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER,
+ vine_dp_get_remote_ip(client_dp, &family, NULL));
+
+ EXPECT_EQ(VINE_ERROR_INVALID_OPERATION,
+ vine_dp_get_remote_ip(server_dp, &family, &ip));
+ EXPECT_EQ(VINE_ERROR_INVALID_OPERATION,
+ vine_dp_get_remote_ip(pubsub_dp, &family, &ip));
+}
+
+TEST_F(VineDpTest, SetGetRemoteIpP)
+{
+ EXPECT_EQ(VINE_ERROR_NONE,
+ vine_dp_set_remote_ip(client_dp, VINE_ADDRESS_FAMILY_IPV4, TEST_IP));
+
+ vine_address_family_e family;
+ char *ip;
EXPECT_EQ(VINE_ERROR_NONE,
- vine_dp_set_remote_ip(client_dp, VINE_ADDRESS_FAMILY_IPV4, "192.168.1.123"));
+ vine_dp_get_remote_ip(client_dp, &family, &ip));
+ EXPECT_EQ(VINE_ADDRESS_FAMILY_IPV4, family);
+ EXPECT_EQ(0, strcmp(TEST_IP, ip));
+ free(ip);
}
TEST_F(VineDpTest, SetPortN)
static void __accepted_cb(vine_dp_h dp, vine_dp_h accepted_dp, void *user_data)
{
printf(MAKE_GREEN "[ACCEPTED_CB] %p is accepted." RESET_COLOR "\n", accepted_dp);
+ vine_address_family_e addr_family;
+ char *ip;
+ int ret = vine_dp_get_remote_ip(accepted_dp, &addr_family, &ip);
+ PRINT_IF_ERROR(ret, "vine_dp_get_remote_ip");
+ printf(MAKE_GREEN " Client IP[%s] Family[%d]" RESET_COLOR "\n", ip, (int)addr_family);
+ free(ip);
__add_new_dp(accepted_dp);
}