From f2fe64b36239e9e5952e14b1eeb03b80a12a9b40 Mon Sep 17 00:00:00 2001 From: guoxiangjun <10622541+carolprincess@user.noreply.gitee.com> Date: Sat, 19 Apr 2025 19:34:27 +0800 Subject: [PATCH] add handover Signed-off-by: guoxiangjun --- include/curl/curl.h | 9 +++++++++ lib/asyn-ares.c | 27 +++++++++++++++++++++++++++ lib/cf-socket.c | 27 ++++++++++++++++++++++++++- lib/easyoptions.c | 5 +++++ lib/setopt.c | 15 +++++++++++++++ lib/url.c | 19 +++++++++++++++++-- lib/urldata.h | 9 +++++++++ 7 files changed, 108 insertions(+), 3 deletions(-) diff --git a/include/curl/curl.h b/include/curl/curl.h index c7aea617a..c6eb0f5dc 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -414,6 +414,7 @@ typedef enum { typedef int (*curl_sockopt_callback)(void *clientp, curl_socket_t curlfd, curlsocktype purpose); +typedef bool (*curl_connreuse_callback)(void *userdata, curl_socket_t curlfd); struct curl_sockaddr { int family; @@ -2216,6 +2217,14 @@ typedef enum { /* set ECH configuration */ CURLOPT(CURLOPT_ECH, CURLOPTTYPE_STRINGPOINT, 325), + CURLOPT(CURLOPT_OHOS_SOCKET_BIND_NET_ID, CURLOPTTYPE_LONG, 1000), + + /* Callback function for deciding url connection reuse */ + CURLOPT(CURLOPT_CONNREUSEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 1001), + + /* Data passed to the CURLOPT_CONNREUSEFUNCTION callback */ + CURLOPT(CURLOPT_CONNREUSEDATA, CURLOPTTYPE_CBPOINT, 1002), + CURLOPT_LASTENTRY /* the last unused */ } CURLoption; diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c index 8fed61760..be67ab447 100644 --- a/lib/asyn-ares.c +++ b/lib/asyn-ares.c @@ -164,6 +164,28 @@ static void sock_state_cb(void *data, ares_socket_t socket_fd, } } +#ifdef OHOS_BIND_NET_BY_FWMARK +int32_t BindSocket(int32_t fd, uint32_t netId); +static int bindohosnetid(ares_socket_t socket_fd, int type, void *data) +{ + struct Curl_easy *easy = (struct Curl_easy *)data; + if (!easy || socket_fd <= 0) { + return -1; + } + unsigned int netid = easy->set.socket_bind_netid; + if (netid > 0) { + int ret = BindSocket(socket_fd, netid); + if (ret == 0) { + return 0; + } else { + // try bind but failed + return -1; + } + } + return 0; +} +#endif + /* * Curl_resolver_init() * @@ -201,6 +223,11 @@ CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver) else return CURLE_FAILED_INIT; } +#ifdef OHOS_BIND_NET_BY_FWMARK + if (easy->set.sock_bind_netid > 0) { + ares_set_socket_configure_callback(resolver, bindohosnetid, easy); + } +#endif return CURLE_OK; /* make sure that all other returns from this function should destroy the ares channel before returning error! */ diff --git a/lib/cf-socket.c b/lib/cf-socket.c index 1340d0951..9e66c7852 100644 --- a/lib/cf-socket.c +++ b/lib/cf-socket.c @@ -398,6 +398,25 @@ void Curl_sndbufset(curl_socket_t sockfd) #endif #ifndef CURL_DISABLE_BINDLOCAL +#ifdef OHOS_BIND_NET_BY_FWMARK +int32_t BindSocket(int32_t fd, uint32_t netId); +static CURLcode bindohosnetid(struct Curl_easy *data, struct connectdata *conn, curl_socket_t sockfd) +{ + unsigned int netid = data->set.socket_bind_netid; + if (netid > 0) { + int ret = BindSocket(socket_fd, netid); + if (ret == 0) { + conn->socket_bind_netid = netid; + return CURLE_OK; + } else { + // try bind but failed + return CURLE_INTERFACE_FAILED; + } + } + return CURLE_OK; +} +#endif + static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn, curl_socket_t sockfd, int af, unsigned int scope) { @@ -426,10 +445,16 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn, /************************************************************* * Select device to bind socket to *************************************************************/ +#ifdef OHOS_BIND_NET_BY_FWMARK + if (!dev && !port) { + /*no local kind of binding was requested */ + return data->set.socket_bind_netid > 0 ? bindohosnetid(data, conn, sockfd): CURLE_OK; + } +#else if(!dev && !port) /* no local kind of binding was requested */ return CURLE_OK; - +#endif memset(&sa, 0, sizeof(struct Curl_sockaddr_storage)); if(dev && (strlen(dev)<255) ) { diff --git a/lib/easyoptions.c b/lib/easyoptions.c index c79d13670..7ab966785 100644 --- a/lib/easyoptions.c +++ b/lib/easyoptions.c @@ -366,6 +366,11 @@ struct curl_easyoption Curl_easyopts[] = { {"XFERINFODATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, 0}, {"XFERINFOFUNCTION", CURLOPT_XFERINFOFUNCTION, CURLOT_FUNCTION, 0}, {"XOAUTH2_BEARER", CURLOPT_XOAUTH2_BEARER, CURLOT_STRING, 0}, +#ifdef OHOS_BIND_NET_BY_FWMARK + {"OHOS_SOCKET_BIND_NET_ID", CURLOPT_OHOS_SOCKET_BIND_NET_ID, CURLOPT_LONG, 0}, +#endif + {"CONNREUSEFUNCTION", CURLOPT_CONNREUSEFUNCTION, CURLOT_FUNCTION, 0}, + {"CONNREUSEDATA", CURLOPT_CONNREUSEDATA, CURLOT_CBPTR, 0}, {NULL, CURLOPT_LASTENTRY, CURLOT_LONG, 0} /* end of table */ }; diff --git a/lib/setopt.c b/lib/setopt.c index e8b25454b..27bedc9fb 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -3174,6 +3174,21 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_QUICK_EXIT: data->set.quick_exit = (0 != va_arg(param, long)) ? 1L:0L; break; +#ifdef OHOS_BIND_NET_BY_FWMARK + case CURLOPT_OHOS_SOCKET_BIND_NET_ID: + uarg = va_arg(param, unsigned long); +#define MAX_NET_ID (0xFFF - 0x400) + if (uarg > MAX_NET_ID) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.socket_bint_netid = uarg; +#endif + break; + case CURLOPT_CONNREUSEFUNCTION: + data->set.fconnreuse = va_arg(param, curl_connreuse_callback); + break; + case CURLOPT_CONNREUSEDATA: + data->set.connreuse_userp = va_arg(param, void *); + break; default: /* unknown tag and its companion, just ignore: */ result = CURLE_UNKNOWN_OPTION; diff --git a/lib/url.c b/lib/url.c index 342049a64..46d8a6a40 100644 --- a/lib/url.c +++ b/lib/url.c @@ -490,6 +490,11 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) memset(&set->priority, 0, sizeof(set->priority)); #endif set->quick_exit = 0L; +#ifdef OHOS_BIND_NET_BY_FWMARK + set->socket_bind_netid = 0; /* OHOS default network */ +#endif + set->fconnreuse = ZERO_NULL; + set->connreuse_userp = ZERO_NULL; return result; } @@ -1325,7 +1330,15 @@ ConnectionExists(struct Curl_easy *data, Curl_disconnect(data, check, TRUE); continue; } - +#ifdef OHOS_BIND_NET_BY_FWMARK + if (check->socket_bind_netid != data->set.socket_bind_netid) { + continue; + } +#endif + if (data->set.fconnreuse && !data->set.fconnreuse(data->set.connreuse_userp, check->sockfd)) { + // no reuse + continue; + } /* We have found a connection. Let's stop searching. */ chosen = check; break; @@ -1454,7 +1467,9 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) conn->closesocket_client = data->set.closesocket_client; conn->lastused = conn->created; conn->gssapi_delegation = data->set.gssapi_delegation; - +#if OHOS_BIND_NET_BY_FWMARK + conn->socket_bind_netid = 0; /* OHOS default net id*/ +#endif return conn; error: diff --git a/lib/urldata.h b/lib/urldata.h index c97c15ad4..1863d6ac3 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1014,6 +1014,10 @@ struct connectdata { unsigned char httpversion; /* the HTTP version*10 reported by the server */ unsigned char connect_only; unsigned char gssapi_delegation; /* inherited from set.gssapi_delegation */ + +#ifdef OHOS_BIND_NET_BY_FWMARK + unsigned int socket_bind_netid; /* OHOS net id*/ +#endif }; #ifndef CURL_DISABLE_PROXY @@ -1876,6 +1880,11 @@ struct UserDefined { #ifdef USE_WEBSOCKETS BIT(ws_raw_mode); #endif +#ifdef OHOS_BIND_NET_BY_FWMARK + unsigned int socket_bind_netid; /* OHOS net id*/ +#endif + curl_connreuse_callback fconnreuse; + void *connreuse_userp; #ifdef USE_ECH int tls_ech; /* TLS ECH configuration */ #endif -- Gitee