Skip to content

Commit 5a95c2c

Browse files
liulanzhenglihuiba
authored andcommitted
support sending requests from different IP for HTTP client
Signed-off-by: liulanzheng <[email protected]>
1 parent bbb814f commit 5a95c2c

File tree

4 files changed

+25
-10
lines changed

4 files changed

+25
-10
lines changed

net/http/client.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class PooledDialer {
4343
photon::mutex init_mtx;
4444
bool initialized = false;
4545
bool tls_ctx_ownership = false;
46+
std::vector<IPAddr> src_ips;
4647

4748
// If there is a photon thread switch during construction, the constructor might be called
4849
// multiple times, even for a thread_local instance. Therefore, ensure that there is no photon
@@ -52,7 +53,7 @@ class PooledDialer {
5253
photon::fini_hook({this, &PooledDialer::at_photon_fini});
5354
}
5455

55-
int init(TLSContext *_tls_ctx) {
56+
int init(TLSContext *_tls_ctx, std::vector<IPAddr> &src_ips) {
5657
if (initialized)
5758
return 0;
5859
SCOPED_LOCK(init_mtx);
@@ -63,8 +64,8 @@ class PooledDialer {
6364
tls_ctx_ownership = true;
6465
tls_ctx = new_tls_context(nullptr, nullptr, nullptr);
6566
}
66-
auto tcp_cli = new_tcp_socket_client();
67-
auto tls_cli = new_tls_client(tls_ctx, new_tcp_socket_client(), true);
67+
auto tcp_cli = new_tcp_socket_client(src_ips.data(), src_ips.size());
68+
auto tls_cli = new_tls_client(tls_ctx, new_tcp_socket_client(src_ips.data(), src_ips.size()), true);
6869
tcpsock.reset(new_tcp_socket_pool(tcp_cli, -1, true));
6970
tlssock.reset(new_tcp_socket_pool(tls_cli, -1, true));
7071
udssock.reset(new_uds_client());
@@ -158,10 +159,9 @@ class ClientImpl : public Client {
158159
m_tls_ctx(tls_ctx),
159160
m_cookie_jar(cookie_jar) {
160161
}
161-
162162
PooledDialer& get_dialer() {
163163
thread_local PooledDialer dialer;
164-
dialer.init(m_tls_ctx);
164+
dialer.init(m_tls_ctx, m_bind_ips);
165165
return dialer;
166166
}
167167

net/http/client.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ limitations under the License.
2525
#include <photon/common/stream.h>
2626
#include <photon/common/timeout.h>
2727
#include <photon/net/socket.h>
28-
28+
#include <vector>
2929

3030
namespace photon {
3131
namespace net {
@@ -129,6 +129,9 @@ class Client : public Object {
129129
void set_user_agent(std::string_view user_agent) {
130130
m_user_agent = std::string(user_agent);
131131
}
132+
void set_bind_ips(std::vector<IPAddr> &ips) {
133+
m_bind_ips = ips;
134+
}
132135
StoredURL* get_proxy() {
133136
return &m_proxy_url;
134137
}
@@ -146,12 +149,13 @@ class Client : public Object {
146149
void timeout_s(uint64_t tmo) { timeout(tmo * 1000UL * 1000UL); }
147150

148151
virtual ISocketStream* native_connect(std::string_view host, uint16_t port,
149-
bool secure = false, uint64_t timeout = -1UL) = 0;
152+
bool secure = false, uint64_t timeout = -1UL) = 0;
150153
protected:
151154
StoredURL m_proxy_url;
152155
std::string m_user_agent;
153156
uint64_t m_timeout = -1UL;
154157
bool m_proxy = false;
158+
std::vector<IPAddr> m_bind_ips;
155159
};
156160

157161
//A Client without cookie_jar would ignore all response-header "Set-Cookies"

net/kernel_socket.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,13 @@ class KernelSocketStream : public SocketStreamBase {
196196

197197
class KernelSocketClient : public SocketClientBase {
198198
public:
199+
std::vector<sockaddr_storage> bind_ss;
200+
201+
KernelSocketClient(IPAddr* bind_ip = nullptr, int bind_ip_n = 0) {
202+
for (int i = 0; i < bind_ip_n; i++)
203+
bind_ss.emplace_back(EndPoint(bind_ip[i], 0));
204+
}
205+
199206
ISocketStream* connect(const char* path, size_t count) override {
200207
struct sockaddr_un addr_un;
201208
if (fill_uds_path(addr_un, path, count) != 0) return nullptr;
@@ -206,6 +213,10 @@ class KernelSocketClient : public SocketClientBase {
206213
ISocketStream* connect(const EndPoint& remote, const EndPoint* local) override {
207214
sockaddr_storage r(remote);
208215
if (likely(!local || local->is_ipv4() != remote.is_ipv4())) {
216+
if (bind_ss.size() > 0) {
217+
int rid = rand() % bind_ss.size();
218+
return do_connect(&r, &bind_ss[rid]);
219+
}
209220
return do_connect(&r);
210221
}
211222
sockaddr_storage l(*local);
@@ -981,8 +992,8 @@ class ETKernelSocketServer : public KernelSocketServer, public NotifyContext {
981992

982993
/* ET Socket - End */
983994

984-
extern "C" ISocketClient* new_tcp_socket_client() {
985-
return new KernelSocketClient();
995+
extern "C" ISocketClient* new_tcp_socket_client(IPAddr* bind_ip, uint32_t bind_ip_n) {
996+
return new KernelSocketClient(bind_ip, bind_ip_n);
986997
}
987998
extern "C" ISocketServer* new_tcp_socket_server() {
988999
return NewObj<KernelSocketServer>()->init();

net/socket.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ namespace net {
278278
virtual void terminate() = 0;
279279
};
280280

281-
extern "C" ISocketClient* new_tcp_socket_client();
281+
extern "C" ISocketClient* new_tcp_socket_client(IPAddr* bind_ip = nullptr, uint32_t bind_ip_n = 0);
282282
extern "C" ISocketServer* new_tcp_socket_server();
283283
extern "C" ISocketClient* new_uds_client();
284284
extern "C" ISocketServer* new_uds_server(bool autoremove = false);

0 commit comments

Comments
 (0)