青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-163  評論-223  文章-30  trackbacks-0
   Web服務器為了支持https訪問,通常會使用第三方庫openssl實現,而且為了高性能采用異步事件驅動模型,因此連接套接字被設為非阻塞類型,本文在nginx ssl模塊的基礎上,簡化提取它的核心框架,使用面向對象的方式描述,從握手、讀寫和關閉3個方面進行了分析,由于這3個操作都是異步的,因此操作失敗后要調用SSL_get_error來獲取錯誤碼,有如下4種情況。
   ● SSL_ERROR_WANT_READ:操作沒完成,需要在下一次讀事件中繼續
   ● SSL_ERROR_WANT_WRITE:操作沒完成,需要在下一次寫事件中繼續
   ● SSL_ERROR_ZERO_RETURN:連接正常關閉
   ● 其它:連接出錯
  
   下面的示例代碼使用了libevent實現IO事件驅動,connection表示普通連接類,假設已經處理好了http數據的邏輯,實現在成員函數handle_read和handle_write內,虛函數recv、send和close分別調用系統的API recv、send和close;ssl_conn_t表示安全連接類,由于只是IO處理不同:收到數據后解密,發送數據前加密。解密后的操作和connection是一樣的,因此ssl_conn_t繼承connection,重寫了recv、send和close,其中close調用了shutdown。

異步握手
   當在SSL端口接受到連接時,首先要進行握手,握手成功后才能收發數據,如果握手失敗而且返回前2種錯誤碼,那么要在下一次操作中繼續握手。
 1void ssl_conn_t::empty_handler(short ev)
 2{
 3}

 4
 5void ssl_conn_t::handshake_handler(short ev)
 6{
 7    handshake();
 8}

 9
10void ssl_conn_t::handshake()
11{
12    int ret = do_handshake();    
13
14    switch(ret){
15        case OP_OK: 
16            read_handler_ = &connection::handle_read;
17            write_handler_ = &connection::handle_write;
18            handle_read(EV_READ);
19            break;
20                 
21    }

22}

23
24int ssl_conn_t::do_handshake()
25{
26    ssl_clear_error();
27
28    int ret = SSL_do_handshake(ssl_);
29    if(1==ret){
30        
31        return OP_OK;
32    }

33    
34    int sslerr = SSL_get_error(ssl_,ret), err;
35    switch(sslerr){
36        case SSL_ERROR_WANT_READ:
37            read_handler_ = (io_handler)&ssl_conn_t::handshake_handler;
38            write_handler_ = (io_handler)&ssl_conn_t::empty_handler;    
39            return OP_AGAIN;
40
41        case SSL_ERROR_WANT_WRITE:
42            read_handler_ = (io_handler)&ssl_conn_t::empty_handler;
43            write_handler_ = (io_handler)&ssl_conn_t::handshake_handler;    
44            return OP_AGAIN;
45         
46    }
                    
47}
    以上do_handshake是核心函數,調用了SSL_do_handshake來實現握手,當SSL_do_handshake失敗時,如果返回SSL_ERROR_WANT_READ,就改變讀函數指針為handshake_handler,寫函數指針為empty_handler;如果返回SSL_ERROR_WANT_WRITE,就改變讀函數指針為empty_handler,寫函數指針為handshake_handler。handshake_handler實現在讀寫事件中繼續處理握手,而empty_handler是個空函數,什么也不做。
   
異步讀寫
   對于讀操作失敗,如果返回SSL_ERROR_WANT_WRITE,那么說明要在下一次寫事件中繼續讀數據,因此要改變寫函數指針,使其讀數據,當讀成功后,要還原寫函數針,并激發一次寫事件;對于寫操作失敗,如果返回SSL_ERROR_WANT_READ,那么說明要在下一次讀事件中繼續寫數據,因此要改變讀函數指針,使其寫數據,當寫成功后,要還原讀函數指針,并激發一次讀事件。如果不還原讀或寫函數指針,那么會發生寫或讀混亂;還原后,要激發一次讀或寫事件,這是為了延續IO事件的進行,防止讀寫餓死。
 1ssize_t ssl_conn_t::recv(void *buf,size_t len)
 2{
 3    ssl_clear_error();
 4
 5    int ret = SSL_read(ssl_,buf,len);
 6    if(ret>0){
 7        if(old_write_handler_){
 8            write_handler_ = old_write_handler_;
 9            old_write_handler_ = NULL;
10            active_event(false);
11        }

12        return ret;
13    }

14
15    int sslerr = SSL_get_error(ssl_,ret), err;
16    switch(sslerr){
17        case SSL_ERROR_WANT_READ:
18            return OP_AGAIN;
19
20        case SSL_ERROR_WANT_WRITE:
21            if(NULL==old_write_handler_){
22                old_write_handler_ = write_handler_;
23                write_handler_ = (io_handler)&ssl_conn_t::write_handler;
24            }

25            return OP_AGAIN;
26           
27    }

28}

29
30void ssl_conn_t::write_handler(short ev)
31{
32    (this->*read_handler_)(EV_WRITE);
33}

34
35ssize_t ssl_conn_t::send(const void *buf,size_t len)
36{
37    ssl_clear_error();
38
39    int ret = SSL_write(ssl_,buf,len);
40    if(ret>0){
41        if(old_read_handler_){
42            read_handler_ = old_read_handler_;
43            old_read_handler_ = NULL;
44            active_event(true);
45        }

46        return ret;
47    }

48
49    int sslerr = SSL_get_error(ssl_,ret), err;
50    switch(sslerr){
51        case SSL_ERROR_WANT_WRITE:
52            return OP_AGAIN;
53
54        case SSL_ERROR_WANT_READ:
55            if(NULL==old_read_handler_){
56                old_read_handler_ = read_handler_;
57                read_handler_ = (io_handler)&ssl_conn_t::read_handler;
58            }

59            return OP_AGAIN;
60        
61    }

62}

63
64void ssl_conn_t::read_handler(short ev)
65{
66    (this->*write_handler_)(EV_READ);
67}
    以上recv調用SSL_read,如果失敗并且返回SSL_ERROR_WANT_WRITE,就保存老的寫函數指針,改變寫函數指針為write_handler,write_handler實現在寫事件中繼續讀數據;send調用SSL_write,如果失敗并且返回SSL_ERROR_WANT_READ,就保存老的讀函數指針,改變讀函數指針為read_handler,read_handler實現在讀事件中繼續寫數據。

異步關閉
   當握手或讀寫因連接關閉或出錯而失敗時,就要關閉連接了,如果失敗并且返回SSL_ERROR_WANT_READ或SSL_ERROR_WANT_WRITE,那么要在下一次讀或寫事件中繼續關閉。在這里,為了收到對方發送的協議退出包而完全退出,等待30秒再關閉,如果超時就直接關閉。
 1void ssl_conn_t::shutdown(bool is_timeout/*=false*/)
 2{
 3    if (do_shutdown(is_timeout) != OP_AGAIN)
 4        delete this;
 5}

 6
 7int ssl_conn_t::do_shutdown(bool is_timeout)
 8{
 9    int  ret,mode;
10
11    if(is_timeout){
12        mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
13        SSL_set_quiet_shutdown(ssl_,1);
14    }
else{
15        
16    }

17    SSL_set_shutdown(ssl_,mode);
18
19    ssl_clear_error();
20
21    ret = SSL_shutdown(ssl_);
22    if(1==ret)
23        return OP_OK;
24
25    int sslerr = SSL_get_error(ssl_,ret), err;
26    switch(sslerr){
27        
28        case SSL_ERROR_WANT_READ:
29        case SSL_ERROR_WANT_WRITE:
30            read_handler_ = (io_handler)&ssl_conn_t::shutdown_handler;
31            write_handler_ = (io_handler)&ssl_conn_t::shutdown_handler;
32
33            if(SSL_ERROR_WANT_READ==sslerr){
34                struct timeval tv;
35                tv.tv_sec = 30,tv.tv_usec = 0;
36                add_event(true,tv);
37            }

38            return OP_AGAIN;
39        
40    }

41}

42
43void ssl_conn_t::shutdown_handler(short ev)
44{
45    shutdown(ev&EV_TIMEOUT);
46}
    以上do_shutdown是核心函數,調用SSL_shutdown實現,如果失敗并且返回SSL_ERROR_WANT_READ或SSL_ERROR_WANT_WRITE,就改變讀寫函數指針為shutdown_handler,shutdown_handler實現在讀寫事件中繼續關閉處理。
posted on 2014-04-11 17:26 春秋十二月 閱讀(14080) 評論(0)  編輯 收藏 引用 所屬分類: Network
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久久久欧美| 亚洲欧美日韩精品| 牛牛影视久久网| 亚洲人成啪啪网站| 亚洲人成网站精品片在线观看| 理论片一区二区在线| 亚洲精品乱码久久久久久日本蜜臀 | 久久久久久久久伊人| 亚洲国产精品99久久久久久久久| 亚洲第一区中文99精品| 欧美日韩免费观看一区| 午夜免费日韩视频| 久久综合狠狠综合久久综青草| 最新高清无码专区| 正在播放欧美视频| 国内精品视频一区| 亚洲人成在线免费观看| 国产精品高清网站| 欧美成人精品在线播放| 欧美午夜精品久久久久久久 | 欧美伊人久久大香线蕉综合69| 欧美亚洲免费在线| 亚洲美女91| 亚洲欧美中文字幕| 亚洲精品少妇| 亚洲综合日本| 日韩视频国产视频| 欧美一区二区三区在线播放| 亚洲国产欧美另类丝袜| 中文精品在线| 亚洲福利视频一区二区| 99国产精品99久久久久久| 国产在线观看一区| 在线视频欧美日韩精品| 在线观看欧美激情| 亚洲一区二区日本| 亚洲精品中文在线| 久久国产福利国产秒拍| 亚洲视频专区在线| 欧美成人伊人久久综合网| 久久国产婷婷国产香蕉| 欧美日韩日本国产亚洲在线| 欧美超级免费视 在线| 国产精品九九| 亚洲人成网站影音先锋播放| 悠悠资源网久久精品| 亚洲一区中文| 亚洲综合色在线| 欧美成人tv| 欧美福利在线观看| 一色屋精品视频免费看| 欧美亚洲一级| 欧美一区二区三区视频在线 | 免费在线日韩av| 久久全国免费视频| 国产欧美va欧美va香蕉在| 99riav久久精品riav| 99国产精品一区| 美女免费视频一区| 欧美大片一区二区三区| 有坂深雪在线一区| 久久精品中文| 久热精品在线| 在线看不卡av| 另类成人小视频在线| 欧美成va人片在线观看| 在线观看日韩www视频免费| 久久精品av麻豆的观看方式| 欧美在线观看视频一区二区| 国产精品入口夜色视频大尺度| 亚洲狼人综合| 午夜精品久久久久久久久久久久久 | 欧美日韩小视频| 99国产精品| 西瓜成人精品人成网站| 国产伦精品一区二区三区| 午夜精品短视频| 久久久久一区二区三区| 激情欧美日韩一区| 免费日韩视频| 一区二区三区精品在线| 欧美一区二区三区精品电影| 黑人巨大精品欧美一区二区| 久久免费的精品国产v∧| 亚洲成色999久久网站| 一区二区三区波多野结衣在线观看| 欧美日韩精品国产| 亚洲欧美日韩人成在线播放| 久久精品夜色噜噜亚洲a∨| 在线精品视频免费观看| 欧美精品手机在线| 亚洲综合日韩在线| 欧美成人乱码一区二区三区| 99视频一区| 国产婷婷色一区二区三区在线 | 另类av一区二区| 亚洲精品久久久久久久久久久久| 亚洲欧美在线另类| 韩日午夜在线资源一区二区| 欧美国产日韩a欧美在线观看| 一区二区三区日韩精品视频| 久久久噜噜噜久久中文字幕色伊伊| 亚洲国产裸拍裸体视频在线观看乱了 | 亚洲欧美日韩中文在线制服| 男女精品网站| 午夜精品一区二区三区在线| 亚洲国产91精品在线观看| 欧美日韩中文精品| 免费观看久久久4p| 午夜视频一区| 一本色道久久综合亚洲精品小说| 麻豆成人小视频| 亚洲天堂av高清| 91久久久一线二线三线品牌| 国产精品日韩精品欧美在线| 欧美国产欧美亚洲国产日韩mv天天看完整 | 亚洲激情视频在线| 久久成人国产精品| 一本色道久久99精品综合| 国内偷自视频区视频综合| 欧美日韩国产小视频在线观看| 久久精品一级爱片| 亚洲一区二区在线| 亚洲毛片一区二区| 亚洲国产专区校园欧美| 乱中年女人伦av一区二区| 欧美一区二区视频网站| 亚洲一卡久久| 99精品国产热久久91蜜凸| 亚洲国产欧美一区二区三区久久| 国产欧美一区二区精品仙草咪| 欧美色播在线播放| 欧美日韩一区高清| 欧美精品激情blacked18| 免费不卡在线观看av| 久久久久九九九九| 久久精品亚洲精品国产欧美kt∨| 欧美一二区视频| 欧美在线视频全部完| 亚洲欧美欧美一区二区三区| 亚洲香蕉在线观看| 一区二区三区高清不卡| 99伊人成综合| av成人毛片| 亚洲一区二区欧美日韩| 亚洲一区二区三区四区中文 | 久久国产免费看| 久久国产精品久久国产精品| 欧美专区日韩视频| 久久久久五月天| 久久综合九色综合久99| 麻豆91精品91久久久的内涵| 久久在线免费观看| 欧美国产精品| 欧美色综合网| 亚洲第一毛片| 亚洲三级影片| 在线综合亚洲欧美在线视频| 制服丝袜亚洲播放| 午夜精品久久久久久久久久久久| 欧美亚洲视频在线观看| 久久久另类综合| 欧美www在线| 国产精品分类| 精品成人乱色一区二区| 亚洲人午夜精品| 亚洲一区二区在线看| 久久99在线观看| 欧美激情亚洲自拍| 一区二区欧美日韩| 久久国产精品99国产| 欧美va亚洲va香蕉在线| 欧美午夜a级限制福利片| 国产日韩欧美综合精品| 亚洲激情另类| 性做久久久久久久免费看| 久久在线视频| 一区二区三区欧美成人| 久久国产精彩视频| 欧美日韩mp4| 激情av一区| 亚洲综合国产| 亚洲国产一区二区视频| 欧美一区二区三区四区视频| 欧美国产第二页| 国产一区二区按摩在线观看| 日韩视频一区二区在线观看 | 欧美一区观看| 亚洲国产精品一区制服丝袜| 亚洲一区二区精品在线| 欧美国产日韩xxxxx| 国产视频欧美视频| 一本色道久久综合狠狠躁篇的优点 | 欧美在线播放一区| 欧美日韩国产美女| 1204国产成人精品视频| 午夜精品久久久久久久99樱桃| 亚洲国产岛国毛片在线| 欧美一区二区三区在线| 欧美丝袜一区二区三区|