Skip to content

Commit 6d9a1c5

Browse files
authored
enh: add support for IPv6 dual-stack in transport layer and related tests (#34370)
1 parent 368e63d commit 6d9a1c5

File tree

7 files changed

+413
-25
lines changed

7 files changed

+413
-25
lines changed

source/libs/transport/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,8 @@ if(${BUILD_WITH_UV_TRANS})
4545
add_definitions(-DUSE_UV)
4646
endif(${BUILD_WITH_UV})
4747
endif(${BUILD_WITH_UV_TRANS})
48+
49+
50+
# if(${BUILD_TEST})
51+
# add_subdirectory(test)
52+
# endif(${BUILD_TEST})

source/libs/transport/src/transCli.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,7 @@ int32_t cliBatchSend(SCliConn* pConn, int8_t direct) {
16911691
if (pReq->pCont == 0) {
16921692
pReq->pCont = (void*)rpcMallocCont(0);
16931693
if (pReq->pCont == NULL) {
1694-
return TSDB_CODE_OUT_OF_MEMORY;
1694+
return terrno;
16951695
}
16961696
pReq->contLen = 0;
16971697
}
@@ -2143,12 +2143,9 @@ static FORCE_INLINE int32_t cliGetIpFromFqdnCache(SHashObj* cache, char* fqdn, S
21432143
code = TSDB_CODE_RPC_FQDN_ERROR;
21442144
tError("ipv6Enable(%d), failed to get ip from fqdn:%s since %s", enableIpv6, fqdn, tstrerror(code));
21452145
return code;
2146-
} else {
2147-
if (enableIpv6 && ipAddr.type != 1) {
2148-
tWarn("get ipv4 addr from fqdn:%s, but ipv6 is enabled", fqdn);
2149-
return TSDB_CODE_RPC_FQDN_ERROR;
2150-
}
21512146
}
2147+
// when enableIpv6=1, both IPv4 and IPv6 addresses are accepted
2148+
// taosGetIpFromFqdn uses AF_UNSPEC and returns first available address
21522149
if ((code = taosHashPut(cache, fqdn, len, &ipAddr, sizeof(ipAddr)) != 0)) {
21532150
return code;
21542151
}

source/libs/transport/src/transSvr.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,11 +1611,25 @@ void uvGetSockInfo(struct sockaddr* addr, SIpAddr* ip) {
16111611
} else if (addr->sa_family == AF_INET6) {
16121612
struct sockaddr_in6* addr_in = (struct sockaddr_in6*)addr;
16131613
ip->port = ntohs(addr_in->sin6_port);
1614-
if (inet_ntop(AF_INET6, &addr_in->sin6_addr, ip->ipv6, INET6_ADDRSTRLEN) == NULL) {
1615-
uInfo("failed to convert ipv6 address");
1614+
1615+
// Check for IPv4-mapped IPv6 address (::ffff:x.x.x.x)
1616+
if (IN6_IS_ADDR_V4MAPPED(&addr_in->sin6_addr)) {
1617+
// Convert IPv4-mapped IPv6 address to IPv4
1618+
struct in_addr ipv4_addr;
1619+
memcpy(&ipv4_addr, ((const uint8_t*)&addr_in->sin6_addr) + 12, sizeof(ipv4_addr));
1620+
if (inet_ntop(AF_INET, &ipv4_addr, ip->ipv4, INET_ADDRSTRLEN) == NULL) {
1621+
uInfo("failed to convert ipv4-mapped ipv6 address to ipv4");
1622+
}
1623+
ip->type = 0;
1624+
ip->mask = 32;
1625+
} else {
1626+
// Pure IPv6 address
1627+
if (inet_ntop(AF_INET6, &addr_in->sin6_addr, ip->ipv6, INET6_ADDRSTRLEN) == NULL) {
1628+
uInfo("failed to convert ipv6 address");
1629+
}
1630+
ip->type = 1;
1631+
ip->mask = 128;
16161632
}
1617-
ip->type = 1;
1618-
ip->mask = 128;
16191633
}
16201634
}
16211635
void uvOnConnectionCb(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf) {
@@ -1859,11 +1873,21 @@ static int32_t addHandleToAcceptloop(void* arg) {
18591873
return TSDB_CODE_THIRDPARTY_ERROR;
18601874
}
18611875

1862-
if ((code = uv_tcp_bind(&srv->server, (const struct sockaddr*)&bind_addr, 1)) != 0) {
1876+
if ((code = uv_tcp_bind(&srv->server, (const struct sockaddr*)&bind_addr, 0)) != 0) {
18631877
tError("failed to bind since %s", uv_err_name(code));
18641878
return TSDB_CODE_THIRDPARTY_ERROR;
18651879
}
1866-
tInfo("bind to ipv6 addr");
1880+
1881+
// set IPV6_V6ONLY to 0 to allow both IPv4 and IPv6 connections
1882+
uv_os_fd_t fd;
1883+
if ((code = uv_fileno((const uv_handle_t*)&srv->server, &fd)) == 0) {
1884+
int opt = 0;
1885+
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) < 0) {
1886+
tWarn("failed to set IPV6_V6ONLY=0: %s, continue with default setting", strerror(errno));
1887+
} else {
1888+
tInfo("successfully set IPV6_V6ONLY=0 (dual-stack enabled)");
1889+
}
1890+
}
18671891
} else {
18681892
struct sockaddr_in bind_addr;
18691893
if ((code = uv_ip4_addr("0.0.0.0", srv->port, &bind_addr)) != 0) {

source/libs/transport/test/CMakeLists.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
add_executable(transportTest "")
22
add_executable(transUT "")
33
add_executable(transUT2 "")
4+
add_executable(transUTIPv6 "")
45
add_executable(svrBench "")
56
add_executable(cliBench "")
67
add_executable(httpBench "")
@@ -14,6 +15,10 @@ target_sources(transUT2
1415
PRIVATE
1516
"transUT2.cpp"
1617
)
18+
target_sources(transUTIPv6
19+
PRIVATE
20+
"transUTIPv6.cpp"
21+
)
1722
target_sources(transportTest
1823
PRIVATE
1924
"transportTests.cpp"
@@ -75,6 +80,21 @@ target_include_directories(transUT2
7580
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
7681
)
7782

83+
84+
DEP_ext_gtest(transUTIPv6)
85+
target_link_libraries(transUTIPv6 PRIVATE
86+
os
87+
util
88+
common
89+
transport
90+
)
91+
92+
target_include_directories(transUTIPv6
93+
PUBLIC
94+
"${TD_SOURCE_DIR}/include/libs/transport"
95+
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
96+
)
97+
7898
target_include_directories(svrBench
7999
PUBLIC
80100
"${TD_SOURCE_DIR}/include/libs/transport"
@@ -125,3 +145,7 @@ add_test(
125145
NAME transUtilUt
126146
COMMAND transportTest
127147
)
148+
add_test(
149+
NAME transUTIPv6
150+
COMMAND transUTIPv6
151+
)

source/libs/transport/test/transUT2.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ TEST_F(TransEnv, http) {
618618
#if 1
619619
STelemAddrMgmt mgt;
620620
taosTelemetryMgtInit(&mgt, "telemetry.taosdata.com");
621-
int32_t code = taosSendTelemReport(&mgt,tsTelemUri, tsTelemPort, "test", strlen("test"),HTTP_FLAT);
621+
code = taosSendTelemReport(&mgt, tsTelemUri, tsTelemPort, "test", strlen("test"), HTTP_FLAT);
622622
printf("old addr:%s new addr:%s\n",mgt.defaultAddr, mgt.cachedAddr);
623623

624624
taosMsleep(2000);

0 commit comments

Comments
 (0)