libcurl 使用 https 时切换 ip 遇到的问题

1 问题由来

开发的产品使用到的某服务器后台接口,因为业务的特殊性,在常规的host访问失败时,需要前端再使用指定的ip访问,而且是https。

开始
使用ip访问https的首要问题就是证书验证流程。在提出此需求时,后台同学给了一份阿里云的参考:HTTPS(含SNI)业务场景“IP直连”方案说明 。此中提到的例子是Andriod和ios上的应用,方案就是在使用的对应库中修改https的证书验证过程,使其最终合法。

而开发的桌面App的网络请求使用的是libcurl实现,于是开始查找文档。半天时间里浏览器了一遍libcurl的文档,也看到了有相关ssl相关的参数控制,但一个是看起来很复杂,一个是也没有找到有效解决问题的方法。同时也在网络搜索,意外找到了github上这篇 DNS污染方案调研/iOS防DNS污染方案调研---SNI业务场景 ,里面有清晰的描述,使用 CURLOPT_RESOLVE。

一测试,果然OK。于是欣喜若狂——绕过验证方法的方式太笨,而且还得改请求的地方,将url中的host改为ip。也感叹,浏览了半天我怎么就是没有看到CURLOPT_RESOLVE这个参数呢。

意外
以上发生在评估阶段。等开始进入实质开发阶段,心想,这次可便宜我了。这个周期的任务——秒提。嘿嘿,就好像少了一个需求。不曾想在严格按照需求开发时发生了意外……

首先实际需求:对servicehost 的每次访问需要显式控制是否要使用指定ip(还是偏向常规访问,用ip嘛,只是备案了)。

一个当前情况:App中使用的请求接口是multi handle(设计之初就是为了同时跑多个请求),恰恰是这点——multi handle ——共用 dns cache 。

评估时只是为了验证,简单的在每一个easy handle初始化时写死了如下调用:

host_list_ = curl_slist_append(NULL, "servicehost:443:8.8.8.8");
curl_easy_setopt(curl_handle, CURLOPT_RESOLVE, host_list_);
也即对 servicehost 的每一次(当然包括第一次了)访问都使用 8.8.8.8 这个ip进行访问——8.8.8.8 被 cache 了。后续就算不想使用这个ip也“不行”。

反过来,如果第一次使用常规访问,dns获取到的是9.9.9.9。从测试结果看,即便后续请求设定了servicehost:443:8.8.8.8,实际请求仍然使用的第一次访问servicehost解析到的9.9.9.9——此次调用CURLOPT_RESOLVE不起作用。看起来好像不管是CURLOPT_RESOLVE调用,还是常规请求,dns都被cache了。

收场
再看文档:Remove names from the DNS cache again, to stop providing these fake resolves, by including a string in the linked list that uses the format "-HOST:PORT".

好了,因为场景中对于servicehost的第一次访问是常规host方式,假设ip是9.9.9.9。后续某次想使用8.8.8.8访问,于是需要移除对应的dns cache。

......
host_list = curl_slist_append(host_list, "-servicehost:443");
host_list = curl_slist_append(host_list, "servicehost:443:8.8.8.8");
curl_easy_setopt(curl, CURLOPT_RESOLVE, host);
......
如果简单粗暴处理,不开启ip直连时,解析url将对应host的dns cache清除。但实际情况是,只有少量的host才有此需求。一刀切,难免影响了绝大多数常规host访问的效率。

我的做法是:记录那些曾经调用了CURLOPT_RESOLVE的hosts。在每一次请求时判断:当前host没有开启ip访问,但在上述hosts中才清理其dns cache,同时从hosts移除记录。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容