mirror of
https://gitee.com/openharmony/communication_dsoftbus
synced 2024-11-23 08:49:59 +00:00
fix: bind to interface
Signed-off-by: liangjunhao <liangjunhao10@huawei.com>
This commit is contained in:
parent
9dffe78f6b
commit
bf45a72ab5
@ -58,6 +58,7 @@ extern "C" {
|
||||
#define SOFTBUS_SO_KEEPALIVE_ SO_KEEPALIVE
|
||||
#define SOFTBUS_SO_REUSEPORT_ SO_REUSEPORT
|
||||
#define SOFTBUS_SO_RCVBUFFORCE_ SO_RCVBUFFORCE
|
||||
#define SOFTBUS_SO_BINDTODEVICE_ SO_BINDTODEVICE
|
||||
|
||||
#define SOFTBUS_TCP_KEEPIDLE_ TCP_KEEPIDLE
|
||||
#define SOFTBUS_TCP_KEEPINTVL_ TCP_KEEPINTVL
|
||||
|
@ -65,6 +65,7 @@ extern "C" {
|
||||
#define SOFTBUS_SO_KEEPALIVE SOFTBUS_SO_KEEPALIVE_
|
||||
#define SOFTBUS_SO_REUSEPORT SOFTBUS_SO_REUSEPORT_
|
||||
#define SOFTBUS_SO_RCVBUFFORCE SOFTBUS_SO_RCVBUFFORCE_
|
||||
#define SOFTBUS_SO_BINDTODEVICE SOFTBUS_SO_BINDTODEVICE_
|
||||
|
||||
#define SOFTBUS_TCP_KEEPIDLE SOFTBUS_TCP_KEEPIDLE_
|
||||
#define SOFTBUS_TCP_KEEPINTVL SOFTBUS_TCP_KEEPINTVL_
|
||||
|
@ -17,10 +17,12 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <securec.h>
|
||||
|
||||
#include "conn_log.h"
|
||||
#include "softbus_adapter_socket.h"
|
||||
#include "softbus_conn_common.h"
|
||||
#include "softbus_def.h"
|
||||
#include "softbus_errcode.h"
|
||||
#include "softbus_tcp_socket.h"
|
||||
@ -483,4 +485,65 @@ bool IsHmlIpAddr(const char *ip)
|
||||
}
|
||||
|
||||
return strncmp(ip, HML_IPV4_ADDR_PREFIX, strlen(HML_IPV4_ADDR_PREFIX)) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t GetIfNameByIp(const char *myIp, int32_t domain, char *ifName, int32_t ifNameMaxLen)
|
||||
{
|
||||
if (myIp == NULL || ifName == NULL) {
|
||||
COMM_LOGE(CONN_COMMON, "Invalid param.");
|
||||
return SOFTBUS_INVALID_PARAM;
|
||||
}
|
||||
|
||||
struct ifaddrs *ifa = NULL;
|
||||
struct ifaddrs *ifList = NULL;
|
||||
struct in_addr inAddr = { 0 };
|
||||
char animizedIp[IP_LEN] = { 0 };
|
||||
ConvertAnonymizeIpAddress(animizedIp, IP_LEN, myIp, IP_LEN);
|
||||
|
||||
int32_t ret = getifaddrs(&ifList);
|
||||
if (ret != 0) {
|
||||
COMM_LOGE(CONN_COMMON, "ip=%{public}s getifaddrs ifList failed, ret=%{public}d", animizedIp, ret);
|
||||
return SOFTBUS_SOCKET_ADDR_ERR;
|
||||
}
|
||||
if (inet_aton(myIp, &inAddr) == 0) {
|
||||
COMM_LOGE(CONN_COMMON, "inet_aton ip=%{public}s failed.", animizedIp);
|
||||
freeifaddrs(ifList);
|
||||
return SOFTBUS_TCP_SOCKET_ERR;
|
||||
}
|
||||
for (ifa = ifList; ifa != NULL; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr == NULL) {
|
||||
continue;
|
||||
}
|
||||
(void)memset_s(ifName, ifNameMaxLen, 0, ifNameMaxLen);
|
||||
if (memcmp(&inAddr, &(((struct sockaddr_in *)ifa->ifa_addr)->sin_addr), sizeof(struct in_addr)) == 0) {
|
||||
if (memcpy_s(ifName, ifNameMaxLen - 1, ifa->ifa_name, strlen(ifa->ifa_name)) != EOK) {
|
||||
COMM_LOGE(CONN_COMMON, "fail to memcpy_s ifName by ip=%{public}s", animizedIp);
|
||||
freeifaddrs(ifList);
|
||||
return SOFTBUS_MEM_ERR;
|
||||
}
|
||||
freeifaddrs(ifList);
|
||||
return SOFTBUS_OK;
|
||||
}
|
||||
}
|
||||
COMM_LOGW(CONN_COMMON, "not found ifName by ip=%{public}s", animizedIp);
|
||||
freeifaddrs(ifList);
|
||||
return SOFTBUS_CONN_NOT_FOUND_FAILED;
|
||||
}
|
||||
|
||||
// prevent the scenario of using VPN to produce virtual network cards.
|
||||
void BindToInterface(const char *myIp, int32_t domain, int fd, char *ifName, int32_t ifNameMaxLen)
|
||||
{
|
||||
// The IPv6 socket has already been bound to the network card, there is no need to bind it again.
|
||||
CONN_CHECK_AND_RETURN_LOGW(domain != SOFTBUS_AF_INET6, CONN_COMMON, "Ipv6 addr no need to get ifName.");
|
||||
|
||||
int32_t ret = GetIfNameByIp(myIp, domain, ifName, ifNameMaxLen);
|
||||
CONN_CHECK_AND_RETURN_LOGW(ret == SOFTBUS_OK, CONN_COMMON, "cannot bind to interface.");
|
||||
|
||||
ret = SoftBusSocketSetOpt(fd, SOFTBUS_SOL_SOCKET, SOFTBUS_SO_BINDTODEVICE, ifName, strlen(ifName));
|
||||
if (ret < 0) {
|
||||
COMM_LOGE(
|
||||
CONN_COMMON, "socketSetOpt fail, fd=%{public}d, ifName=%{public}s, errno=%{public}d", fd, ifName, ret);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -223,6 +223,8 @@ static int32_t OpenTcpServerSocket(const LocalListenerInfo *option)
|
||||
ConnShutdownSocket(fd);
|
||||
return SOFTBUS_SOCKET_BIND_ERR;
|
||||
}
|
||||
|
||||
BindToInterface(option->socketOption.addr, domain, fd, (char *)(option->socketOption.ifName), IF_NAME_SIZE);
|
||||
CONN_LOGI(CONN_COMMON, "server listen tcp socket, fd=%{public}d", fd);
|
||||
return fd;
|
||||
}
|
||||
@ -272,8 +274,7 @@ static int32_t SocketConnect(int32_t fd, int32_t domain, const ConnectOption *op
|
||||
|
||||
static int32_t OpenTcpClientSocket(const ConnectOption *option, const char *myIp, bool isNonBlock)
|
||||
{
|
||||
CONN_CHECK_AND_RETURN_RET_LOGW(option != NULL, SOFTBUS_INVALID_PARAM, CONN_COMMON,
|
||||
"invalid param, option is null");
|
||||
CONN_CHECK_AND_RETURN_RET_LOGW(option != NULL, SOFTBUS_INVALID_PARAM, CONN_COMMON, "invalid param, null option");
|
||||
CONN_CHECK_AND_RETURN_RET_LOGW(option->type == CONNECT_TCP || option->type == CONNECT_P2P ||
|
||||
option->type == CONNECT_P2P_REUSE || option->type == CONNECT_HML, SOFTBUS_INVALID_PARAM, CONN_COMMON,
|
||||
"invalid param, unsupport type=%{public}d", option->type);
|
||||
@ -311,6 +312,8 @@ static int32_t OpenTcpClientSocket(const ConnectOption *option, const char *myIp
|
||||
ConnShutdownSocket(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BindToInterface(myIp, domain, fd, (char *)(option->socketOption.ifName), IF_NAME_SIZE);
|
||||
ret = SocketConnect(fd, domain, option);
|
||||
if ((ret != SOFTBUS_ADAPTER_OK) && (ret != SOFTBUS_ADAPTER_SOCKET_EINPROGRESS) &&
|
||||
(ret != SOFTBUS_ADAPTER_SOCKET_EAGAIN)) {
|
||||
|
@ -71,6 +71,7 @@ typedef enum {
|
||||
#define CONN_INVALID_LISTENER_MODULE_ID 0xffff
|
||||
#define CONN_DYNAMIC_LISTENER_MODULE_COUNT 32
|
||||
#define DEVID_BUFF_LEN 65
|
||||
#define NETIF_NAME_LEN 16
|
||||
|
||||
#define BT_LINK_TYPE_BR 1
|
||||
#define BT_LINK_TYPE_BLE 2
|
||||
@ -187,6 +188,7 @@ struct SocketOption {
|
||||
int32_t moduleId; /* For details, see {@link ListenerModule}. */
|
||||
ProtocolType protocol;
|
||||
int32_t keepAlive;
|
||||
char ifName[NETIF_NAME_LEN];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@ -219,6 +221,7 @@ struct ListenerSocketOption {
|
||||
int32_t port;
|
||||
ListenerModule moduleId; /* For details, see {@link ListenerModule}. */
|
||||
ProtocolType protocol;
|
||||
char ifName[NETIF_NAME_LEN];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -90,6 +90,8 @@ int32_t Ipv6AddrInToAddr(SoftBusSockAddrIn6 *addrIn6, char *addr, int32_t addrLe
|
||||
int32_t Ipv6AddrToAddrIn(SoftBusSockAddrIn6 *addrIn6, const char *ip, uint16_t port);
|
||||
int32_t Ipv4AddrToAddrIn(SoftBusSockAddrIn *addrIn, const char *ip, uint16_t port);
|
||||
|
||||
void BindToInterface(const char *myIp, int32_t domain, int fd, char *ifName, int32_t ifNameMaxLen);
|
||||
|
||||
bool IsHmlIpAddr(const char *ip);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -641,7 +641,7 @@ static int32_t OnVerifyP2pRequest(AuthHandle authHandle, int64_t seq, const cJSO
|
||||
return SOFTBUS_OK;
|
||||
}
|
||||
|
||||
static int32_t ConnectTcpDirectPeer(const char *addr, int port)
|
||||
static int32_t ConnectTcpDirectPeer(const char *addr, int port, const char *myIp)
|
||||
{
|
||||
ConnectOption options;
|
||||
if (IsHmlIpAddr(addr)) {
|
||||
@ -660,7 +660,7 @@ static int32_t ConnectTcpDirectPeer(const char *addr, int port)
|
||||
return SOFTBUS_STRCPY_ERR;
|
||||
}
|
||||
|
||||
return ConnOpenClientSocket(&options, BIND_ADDR_ALL, true);
|
||||
return ConnOpenClientSocket(&options, myIp, true);
|
||||
}
|
||||
|
||||
static int32_t AddHmlTrigger(int32_t fd, const char *myAddr, int64_t seq)
|
||||
@ -744,7 +744,7 @@ static int32_t OnVerifyP2pReply(int64_t authId, int64_t seq, const cJSON *json)
|
||||
}
|
||||
TRANS_LOGI(TRANS_CTRL, "peer wifi: peerPort=%{public}d", conn->appInfo.peerData.port);
|
||||
|
||||
fd = ConnectTcpDirectPeer(conn->appInfo.peerData.addr, conn->appInfo.peerData.port);
|
||||
fd = ConnectTcpDirectPeer(conn->appInfo.peerData.addr, conn->appInfo.peerData.port, conn->appInfo.myData.addr);
|
||||
if (fd <= 0) {
|
||||
ReleaseSessionConnLock();
|
||||
TRANS_LOGE(TRANS_CTRL, "conn fail: fd=%{public}d", fd);
|
||||
|
@ -156,7 +156,7 @@ int32_t OpenTcpDirectChannel(const AppInfo *appInfo, const ConnectOption *connIn
|
||||
return SOFTBUS_TRANS_TCP_GET_AUTHID_FAILED;
|
||||
}
|
||||
|
||||
int32_t fd = ConnOpenClientSocket(connInfo, BIND_ADDR_ALL, true);
|
||||
int32_t fd = ConnOpenClientSocket(connInfo, newConn->appInfo.myData.addr, true);
|
||||
if (fd < 0) {
|
||||
FreeFastTransData(&(newConn->appInfo));
|
||||
SoftBusFree(newConn);
|
||||
|
@ -39,10 +39,13 @@ group("unittest") {
|
||||
"trans_channel/udp_negotiation:unittest",
|
||||
]
|
||||
if (has_enhance_test) {
|
||||
deps += [ "$dsoftbus_root_path/dsoftbus_enhance/test/core/transmission/trans_channel:unittest" ]
|
||||
deps += [ "$dsoftbus_root_path/dsoftbus_enhance/test/core/transmission/session:unittest" ]
|
||||
deps += [ "$dsoftbus_root_path/dsoftbus_enhance/test/core/transmission/spe:unittest" ]
|
||||
deps += [ "$dsoftbus_root_path/dsoftbus_enhance/test/core/transmission/manager:unittest" ]
|
||||
deps += [
|
||||
"$dsoftbus_root_path/dsoftbus_enhance/test/core/transmission/ipc:unittest",
|
||||
"$dsoftbus_root_path/dsoftbus_enhance/test/core/transmission/manager:unittest",
|
||||
"$dsoftbus_root_path/dsoftbus_enhance/test/core/transmission/session:unittest",
|
||||
"$dsoftbus_root_path/dsoftbus_enhance/test/core/transmission/spe:unittest",
|
||||
"$dsoftbus_root_path/dsoftbus_enhance/test/core/transmission/trans_channel:unittest",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ using namespace testing::ext;
|
||||
#define P2P_IP "P2P_IP"
|
||||
#define ERR_CODE "ERR_CODE"
|
||||
static const char *IP = "192.168.8.1";
|
||||
static const char *MY_IP = "192.168.8.13";
|
||||
static const char *DATA = "test_send_data";
|
||||
static const char *SESSION_NAME = "com.test.trans.auth.demo";
|
||||
static const char *PKGE_NAME = "dms";
|
||||
@ -520,11 +521,11 @@ HWTEST_F(TransTcpDirectP2pMockTest, ConnectTcpDirectPeerTest001, TestSize.Level1
|
||||
NiceMock<TransTcpDirectP2pInterfaceMock> TcpP2pDirectMock;
|
||||
EXPECT_CALL(TcpP2pDirectMock, IsHmlIpAddr).WillOnce(Return(false));
|
||||
EXPECT_CALL(TcpP2pDirectMock, ConnOpenClientSocket).WillOnce(Return(SOFTBUS_NO_INIT));
|
||||
int32_t ret = ConnectTcpDirectPeer(IP, TEST_PORT);
|
||||
int32_t ret = ConnectTcpDirectPeer(IP, TEST_PORT, MY_IP);
|
||||
EXPECT_EQ(SOFTBUS_NO_INIT, ret);
|
||||
EXPECT_CALL(TcpP2pDirectMock, IsHmlIpAddr).WillOnce(Return(true));
|
||||
EXPECT_CALL(TcpP2pDirectMock, ConnOpenClientSocket).WillOnce(Return(SOFTBUS_OK));
|
||||
ret = ConnectTcpDirectPeer(IP, TEST_PORT);
|
||||
ret = ConnectTcpDirectPeer(IP, TEST_PORT, MY_IP);
|
||||
EXPECT_EQ(SOFTBUS_OK, ret);
|
||||
}
|
||||
|
||||
|
@ -345,7 +345,7 @@ HWTEST_F(TransTcpDirectP2pTest, OnVerifyP2pRequestTest001, TestSize.Level1)
|
||||
*/
|
||||
HWTEST_F(TransTcpDirectP2pTest, ConnectTcpDirectPeerTest001, TestSize.Level1)
|
||||
{
|
||||
int32_t ret = ConnectTcpDirectPeer(g_addr, g_port);
|
||||
int32_t ret = ConnectTcpDirectPeer(g_addr, g_port, g_ip);
|
||||
EXPECT_EQ(ret, SOFTBUS_CONN_SOCKET_GET_INTERFACE_ERR);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user