浏览代码

fix #193: add hio_set_hostname for hssl_set_sni_hostname

ithewei 3 年之前
父节点
当前提交
6c0ae4c998
共有 8 个文件被更改,包括 50 次插入15 次删除
  1. 1 1
      base/hsocket.h
  2. 11 0
      event/hevent.c
  3. 2 1
      event/hevent.h
  4. 4 1
      event/hloop.h
  5. 4 0
      event/nio.c
  6. 5 0
      evpp/Channel.h
  7. 17 10
      evpp/TcpClient.h
  8. 6 2
      http/client/AsyncHttpClient.cpp

+ 1 - 1
base/hsocket.h

@@ -139,7 +139,7 @@ HV_EXPORT int Connect(const char* host, int port, int nonblock DEFAULT(0));
 // Connect(host, port, 1)
 HV_EXPORT int ConnectNonblock(const char* host, int port);
 // Connect(host, port, 1) -> select -> blocking
-#define DEFAULT_CONNECT_TIMEOUT 5000 // ms
+#define DEFAULT_CONNECT_TIMEOUT 10000 // ms
 HV_EXPORT int ConnectTimeout(const char* host, int port, int ms DEFAULT(DEFAULT_CONNECT_TIMEOUT));
 
 #ifdef ENABLE_UDS

+ 11 - 0
event/hevent.c

@@ -139,6 +139,7 @@ void hio_ready(hio_t* io) {
     io->ssl = NULL;
     io->ssl_ctx = NULL;
     io->alloced_ssl_ctx = 0;
+    io->hostname = NULL;
     // context
     io->ctx = NULL;
     // private:
@@ -479,6 +480,16 @@ int hio_new_ssl_ctx(hio_t* io, hssl_ctx_opt_t* opt) {
     return hio_set_ssl_ctx(io, ssl_ctx);
 }
 
+int hio_set_hostname(hio_t* io, const char* hostname) {
+    SAFE_FREE(io->hostname);
+    io->hostname = strdup(hostname);
+    return 0;
+}
+
+const char* hio_get_hostname(hio_t* io) {
+    return io->hostname;
+}
+
 void hio_del_connect_timer(hio_t* io) {
     if (io->connect_timer) {
         htimer_del(io->connect_timer);

+ 2 - 1
event/hevent.h

@@ -98,7 +98,7 @@ struct hperiod_s {
 };
 
 QUEUE_DECL(offset_buf_t, write_queue);
-// sizeof(struct hio_s)=408 on linux-x64
+// sizeof(struct hio_s)=416 on linux-x64
 struct hio_s {
     HEVENT_FIELDS
     // flags
@@ -167,6 +167,7 @@ struct hio_s {
     // ssl
     void*       ssl;        // for hio_set_ssl
     void*       ssl_ctx;    // for hio_set_ssl_ctx
+    char*       hostname;   // for hssl_set_sni_hostname
     // context
     void*       ctx; // for hio_context / hio_set_context
 // private:

+ 4 - 1
event/hloop.h

@@ -115,7 +115,7 @@ typedef enum {
     HIO_CLIENT_SIDE  = 1,
 } hio_side_e;
 
-#define HIO_DEFAULT_CONNECT_TIMEOUT     5000    // ms
+#define HIO_DEFAULT_CONNECT_TIMEOUT     10000   // ms
 #define HIO_DEFAULT_CLOSE_TIMEOUT       60000   // ms
 #define HIO_DEFAULT_KEEPALIVE_TIMEOUT   75000   // ms
 #define HIO_DEFAULT_HEARTBEAT_INTERVAL  10000   // ms
@@ -312,6 +312,9 @@ HV_EXPORT int  hio_set_ssl_ctx(hio_t* io, hssl_ctx_t ssl_ctx);
 HV_EXPORT int  hio_new_ssl_ctx(hio_t* io, hssl_ctx_opt_t* opt);
 HV_EXPORT hssl_t     hio_get_ssl(hio_t* io);
 HV_EXPORT hssl_ctx_t hio_get_ssl_ctx(hio_t* io);
+// for hssl_set_sni_hostname
+HV_EXPORT int         hio_set_hostname(hio_t* io, const char* hostname);
+HV_EXPORT const char* hio_get_hostname(hio_t* io);
 
 // connect timeout => hclose_cb
 HV_EXPORT void hio_set_connect_timeout(hio_t* io, int timeout_ms DEFAULT(HIO_DEFAULT_CONNECT_TIMEOUT));

+ 4 - 0
event/nio.c

@@ -212,6 +212,9 @@ static void nio_connect(hio_t* io) {
                 }
                 io->ssl = ssl;
             }
+            if (io->hostname) {
+                hssl_set_sni_hostname(io->ssl, io->hostname);
+            }
             ssl_client_handshake(io);
         }
         else {
@@ -572,6 +575,7 @@ int hio_close (hio_t* io) {
         hssl_ctx_free(io->ssl_ctx);
         io->ssl_ctx = NULL;
     }
+    SAFE_FREE(io->hostname);
     if (io->io_type & HIO_TYPE_SOCKET) {
         closesocket(io->fd);
     }

+ 5 - 0
evpp/Channel.h

@@ -226,6 +226,11 @@ public:
         if (io_ == NULL) return -1;
         return hio_new_ssl_ctx(io_, opt);
     }
+    // for hssl_set_sni_hostname
+    int setHostname(const std::string& hostname) {
+        if (io_ == NULL) return -1;
+        return hio_set_hostname(io_, hostname.c_str());
+    }
 
     // timeout
     void setConnectTimeout(int timeout_ms) {

+ 17 - 10
evpp/TcpClient.h

@@ -16,7 +16,7 @@ public:
     typedef std::shared_ptr<TSocketChannel> TSocketChannelPtr;
 
     TcpClientTmpl() {
-        connect_timeout = 5000;
+        connect_timeout = HIO_DEFAULT_CONNECT_TIMEOUT;
         tls = false;
         tls_setting = NULL;
         reconn_setting = NULL;
@@ -36,16 +36,18 @@ public:
     //NOTE: By default, not bind local port. If necessary, you can call system api bind() after createsocket().
     //@retval >=0 connfd, <0 error
     int createsocket(int remote_port, const char* remote_host = "127.0.0.1") {
-        memset(&peeraddr, 0, sizeof(peeraddr));
-        int ret = sockaddr_set_ipport(&peeraddr, remote_host, remote_port);
+        memset(&remote_addr, 0, sizeof(remote_addr));
+        int ret = sockaddr_set_ipport(&remote_addr, remote_host, remote_port);
         if (ret != 0) {
             return -1;
         }
-        return createsocket(&peeraddr.sa);
+        this->remote_host = remote_host;
+        this->remote_port = remote_port;
+        return createsocket(&remote_addr.sa);
     }
-    int createsocket(struct sockaddr* peeraddr) {
-        int connfd = socket(peeraddr->sa_family, SOCK_STREAM, 0);
-        // SOCKADDR_PRINT(peeraddr);
+    int createsocket(struct sockaddr* remote_addr) {
+        int connfd = socket(remote_addr->sa_family, SOCK_STREAM, 0);
+        // SOCKADDR_PRINT(remote_addr);
         if (connfd < 0) {
             perror("socket");
             return -2;
@@ -53,7 +55,7 @@ public:
 
         hio_t* io = hio_get(loop_thread.hloop(), connfd);
         assert(io != NULL);
-        hio_set_peeraddr(io, peeraddr, SOCKADDR_LEN(peeraddr));
+        hio_set_peeraddr(io, remote_addr, SOCKADDR_LEN(remote_addr));
         channel.reset(new TSocketChannel(io));
         return connfd;
     }
@@ -75,6 +77,9 @@ public:
             if (tls_setting) {
                 channel->newSslCtx(tls_setting);
             }
+            if (!is_ipaddr(remote_host.c_str())) {
+                channel->setHostname(remote_host);
+            }
         }
         channel->onconnect = [this]() {
             if (unpack_setting) {
@@ -120,7 +125,7 @@ public:
         uint32_t delay = reconn_setting_calc_delay(reconn_setting);
         loop_thread.loop()->setTimeout(delay, [this](TimerID timerID){
             hlogi("reconnect... cnt=%d, delay=%d", reconn_setting->cur_retry_cnt, reconn_setting->cur_delay);
-            if (createsocket(&peeraddr.sa) < 0) return;
+            if (createsocket(&remote_addr.sa) < 0) return;
             startConnect();
         });
         return 0;
@@ -196,7 +201,9 @@ public:
 public:
     TSocketChannelPtr       channel;
 
-    sockaddr_u              peeraddr;
+    std::string             remote_host;
+    int                     remote_port;
+    sockaddr_u              remote_addr;
     int                     connect_timeout;
     bool                    tls;
     hssl_ctx_opt_t*         tls_setting;

+ 6 - 2
http/client/AsyncHttpClient.cpp

@@ -19,9 +19,10 @@ int AsyncHttpClient::doTask(const HttpClientTaskPtr& task) {
     req->ParseUrl();
     sockaddr_u peeraddr;
     memset(&peeraddr, 0, sizeof(peeraddr));
-    int ret = sockaddr_set_ipport(&peeraddr, req->host.c_str(), req->port);
+    const char* host = req->host.c_str();
+    int ret = sockaddr_set_ipport(&peeraddr, host, req->port);
     if (ret != 0) {
-        hloge("unknown host %s", req->host.c_str());
+        hloge("unknown host %s", host);
         return -20;
     }
 
@@ -49,6 +50,9 @@ int AsyncHttpClient::doTask(const HttpClientTaskPtr& task) {
         // https
         if (req->IsHttps() && !req->IsProxy()) {
             hio_enable_ssl(connio);
+            if (!is_ipaddr(host)) {
+                hio_set_hostname(connio, host);
+            }
         }
     }