diff options
| author | 郑超 <[email protected]> | 2019-02-27 13:04:40 +0800 |
|---|---|---|
| committer | 郑超 <[email protected]> | 2019-02-27 13:04:40 +0800 |
| commit | 473b7e63b3dce4c6409bb597839dae7eb73eea15 (patch) | |
| tree | 7b6d4d18391d3a71e397162cd18cac79032b3bac | |
| parent | ef62705899c5c7b5465c4d328e114712e5ab75b8 (diff) | |
| parent | 2d57f7506223ce9c15b5c0c8b94d4eae581929a1 (diff) | |
Merge branch 'bugfix-downstream-timeout-on-winscale-1' into 'master'
正确处理只有一方发送wscale option的情况,删除注释掉的代码。
See merge request tango/kni!4
| -rw-r--r-- | kni_comm.c | 102 | ||||
| -rw-r--r-- | kni_comm.h | 3 | ||||
| -rw-r--r-- | kni_entry.c | 11 | ||||
| -rw-r--r-- | kni_entry.h | 8 | ||||
| -rw-r--r-- | kni_intercept.c | 61 |
5 files changed, 48 insertions, 137 deletions
@@ -349,10 +349,10 @@ int kni_get_tcpinfo(struct kni_wndpro_reply_info* lastpkt_info,struct kni_tcp_hd #include <netinet/tcp.h> void kni_get_tcpopt(struct kni_tcp_hdr* tcphdr,int tcp_hdr_len, - unsigned short* mss,unsigned char* winscale,unsigned char* scak,unsigned char* timestamps) + unsigned short* mss, unsigned char* wscale_perm, unsigned char* wscale, unsigned char* sack, unsigned char* timestamps) { *mss=KNI_DEFAULT_MSS; - *winscale=KNI_DEFAULT_WINSCLE; + *wscale=KNI_DEFAULT_WINSCLE; const unsigned char *ptr = ((const unsigned char*)tcphdr+TCPHDR_DEFAULT_LEN); int length = tcp_hdr_len - TCPHDR_DEFAULT_LEN; @@ -388,7 +388,15 @@ void kni_get_tcpopt(struct kni_tcp_hdr* tcphdr,int tcp_hdr_len, if (opsize == TCPOLEN_WINDOW) { uint8_t snd_wscale = *(uint8_t *)ptr; - *winscale = snd_wscale; + // rfc7323 page9: Thus, the shift count MUST be limited to 14 (which allows windows of 2^30 = 1 GiB). + // If a Window Scale option is received with a shift.cnt value larger than 14, + // the TCP SHOULD log the error but MUST use 14 instead of the specified value. */ + *wscale = snd_wscale; + if(*wscale>14) + { + *wscale=14; + } + *wscale_perm=1; } break; case TCPOPT_TIMESTAMP: @@ -400,7 +408,7 @@ void kni_get_tcpopt(struct kni_tcp_hdr* tcphdr,int tcp_hdr_len, case TCPOPT_SACK_PERMITTED: if (opsize == TCPOLEN_SACK_PERMITTED) { - *scak = 1; + *sack = 1; } break; } @@ -412,92 +420,6 @@ void kni_get_tcpopt(struct kni_tcp_hdr* tcphdr,int tcp_hdr_len, return; } -/* -int kni_get_tcpopt(struct kni_tcp_hdr* tcphdr,int tcp_hdr_len,unsigned short* mss,unsigned char* winscale,unsigned char* scak,unsigned char* timestamps) -{ - - *mss=KNI_DEFAULT_MSS; - *winscale=KNI_DEFAULT_WINSCLE; - - - int remain_len=tcp_hdr_len; - struct kni_tcp_opt_format* tcp_opt=NULL; - - if((tcp_hdr_len<=20)||(tcp_hdr_len>64)) - { - return 0; - } - - tcp_opt=(struct kni_tcp_opt_format*)((char*)tcphdr+TCPHDR_DEFAULT_LEN); - remain_len-=TCPHDR_DEFAULT_LEN; - - while(remain_len) - { - unsigned int tcp_opt_len; - if(tcp_opt->type == 0 || tcp_opt->type == 1) - { - tcp_opt_len = 1; - } - else - { - tcp_opt_len = tcp_opt->len; - } - - if(tcp_opt_len > remain_len) - { - break; - } - - if(tcp_opt->type==KNI_TCPOPT_MSS) //MSS - { - remain_len-=tcp_opt->len; - *mss=htons(*(unsigned short*)(tcp_opt->content)); - tcp_opt=(struct kni_tcp_opt_format*)((char*)tcp_opt+tcp_opt->len); - - continue; - } - else if(tcp_opt->type==KNI_TCPOPT_WINSCALE) //winscale - { - remain_len-=tcp_opt->len; - *winscale=*(unsigned char*)(tcp_opt->content); - tcp_opt=(struct kni_tcp_opt_format*)((char*)tcp_opt+tcp_opt->len); - - continue; - } - else if(tcp_opt->type==KNI_TCPOPT_SACKOK) //scak - { - remain_len-=tcp_opt->len; - *scak=1; - tcp_opt=(struct kni_tcp_opt_format*)((char*)tcp_opt+tcp_opt->len); - - continue; - } - else if(tcp_opt->type==KNI_TCPOPT_TIMESTAMP) //timestamp - { - remain_len-=tcp_opt->len; - *timestamps=1; - tcp_opt=(struct kni_tcp_opt_format*)((char*)tcp_opt+tcp_opt->len); - - continue; - } - else if((tcp_opt->type==0)||(tcp_opt->type==1)) - { - remain_len-=1; - tcp_opt=(struct kni_tcp_opt_format*)((char*)tcp_opt+1); - continue; - } - else - { - remain_len-=tcp_opt->len; - tcp_opt=(struct kni_tcp_opt_format*)((char*)tcp_opt+tcp_opt->len); - continue; - } - } - - return 0; - -}*/ - char* kni_get_payload(const struct streaminfo* pstream,int* datalen) { char* data=NULL; @@ -88,7 +88,8 @@ int kni_get_ipaddr_v4(void* a_packet,struct stream_tuple4_v4* ipaddr); int kni_get_ipaddr_v6(void* a_packet,struct stream_tuple4_v6* ipaddr); int kni_get_tcpinfo(struct kni_wndpro_reply_info* lastpkt_info,struct kni_tcp_hdr* tcphdr,int tcplen); -void kni_get_tcpopt(struct kni_tcp_hdr* tcphdr,int tcp_hdr_len,unsigned short* mss,unsigned char* winscale,unsigned char* scak,unsigned char* timestamps); +void kni_get_tcpopt(struct kni_tcp_hdr* tcphdr,int tcp_hdr_len, + unsigned short* mss, unsigned char* wscale_perm, unsigned char* wscale, unsigned char* sack, unsigned char* timestamps); char* kni_get_payload(const struct streaminfo* pstream,int* datalen); int kni_filestate2_set(int thread_seq,enum kni_FS_COLUME colum_index,int bytes,int pktnum); diff --git a/kni_entry.c b/kni_entry.c index ee2ce92..fdaf35d 100644 --- a/kni_entry.c +++ b/kni_entry.c @@ -789,7 +789,10 @@ char kni_pending_opstate(const struct streaminfo* pstream,struct kni_pme_info* p if(protocol == PROTO_TYPE_TCP) { - kni_get_tcpopt(tcphdr,tcphdr_len,&(pmeinfo->tcpopt_info[pstream->curdir-1].mss),&(pmeinfo->tcpopt_info[pstream->curdir-1].wnscal),&(pmeinfo->tcpopt_info[pstream->curdir-1].sack),&(pmeinfo->tcpopt_info[pstream->curdir-1].timestamps)); + kni_get_tcpopt(tcphdr, tcphdr_len, + &(pmeinfo->tcpopt_info[pstream->curdir-1].mss), + &(pmeinfo->tcpopt_info[pstream->curdir-1].wscale_perm), &(pmeinfo->tcpopt_info[pstream->curdir-1].wscale), + &(pmeinfo->tcpopt_info[pstream->curdir-1].sack_perm), &(pmeinfo->tcpopt_info[pstream->curdir-1].timestamps)); kni_get_tcpinfo(&(pmeinfo->lastpkt_info[pstream->curdir-1]),tcphdr,datalen); if(datalen>0)//TODO:get link create mode from sapp @@ -886,7 +889,11 @@ char kni_data_opstate(const struct streaminfo* pstream,struct kni_pme_info* pmei { if((tcphdr->th_flags&TH_SYN)&&(tcphdr->th_flags&TH_ACK)) { - kni_get_tcpopt(tcphdr,tcphdr_len,&(pmeinfo->tcpopt_info[pstream->curdir-1].mss),&(pmeinfo->tcpopt_info[pstream->curdir-1].wnscal),&(pmeinfo->tcpopt_info[pstream->curdir-1].sack),&(pmeinfo->tcpopt_info[pstream->curdir-1].timestamps)); + kni_get_tcpopt(tcphdr, tcphdr_len, + &(pmeinfo->tcpopt_info[pstream->curdir-1].mss), + &(pmeinfo->tcpopt_info[pstream->curdir-1].wscale_perm), &(pmeinfo->tcpopt_info[pstream->curdir-1].wscale), + &(pmeinfo->tcpopt_info[pstream->curdir-1].sack_perm), + &(pmeinfo->tcpopt_info[pstream->curdir-1].timestamps)); } kni_get_tcpinfo(&(pmeinfo->lastpkt_info[pstream->curdir-1]),tcphdr,datalen); diff --git a/kni_entry.h b/kni_entry.h index 4e2cbdb..ae0a318 100644 --- a/kni_entry.h +++ b/kni_entry.h @@ -337,9 +337,10 @@ struct kni_wndpro_reply_info struct kni_tcpopt_info { - unsigned short mss; //host order - unsigned char wnscal; //host order - unsigned char sack; + unsigned short mss; //host order + unsigned char wscale_perm; + unsigned char wscale; //host order + unsigned char sack_perm; unsigned char timestamps; }; @@ -403,6 +404,7 @@ struct kni_tcp_state unsigned short win; unsigned short mss_src; unsigned short mss_dst; + unsigned char wscale_perm; unsigned char wscale_src; unsigned char wscale_dst; unsigned char sack_src; diff --git a/kni_intercept.c b/kni_intercept.c index 5e861b2..3d5e68f 100644 --- a/kni_intercept.c +++ b/kni_intercept.c @@ -322,8 +322,7 @@ int tun_alloc_mq(char *dev, int queues, int *fds,char* tun_path) int i=0; int err=0; int fd; - int flag=0; - struct ifreq ifr; + struct ifreq ifr; // char *clonedev = (char*)"/dev/net/tun"; @@ -904,34 +903,10 @@ int tun_read_data(int fd, char* buffer, size_t size) { int recv_len=0; - int ret=0; - int max_fd = 0; -/* - if(g_kni_switch_info.write_listq_switch == 0) - { - fd_set alive_readfd; - struct timeval timeout; - memset(&timeout,0,sizeof(timeout)); - - - FD_ZERO(&alive_readfd); - FD_SET(fd, &alive_readfd); - max_fd = fd; - - // ret = select(max_fd + 1, &alive_readfd, NULL, NULL, &timeout); - ret = select(max_fd + 1, &alive_readfd, NULL, NULL, NULL); - if (ret < 0) - { - // MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL, "keep_alive_action function", "select function errno %d is %s!", errno, strerror(errno)); - return 0; - } - } -*/ recv_len = read(fd, buffer, size); if(recv_len <0) { -// MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_WRITETUN,"tun_read_data error %d, %s\n",errno,strerror(errno)); - return -1; + return -1; } else { @@ -1216,10 +1191,11 @@ int tcprepair_get_state(int curdir,const struct layer_addr* addr,struct kni_tcp_ fake_client->ack=ntohl(tcphdr->th_ack); fake_client->mss_src=pmeinfo->tcpopt_info[KNI_DIR_C2S].mss; fake_client->mss_dst=pmeinfo->tcpopt_info[KNI_DIR_S2C].mss; - fake_client->wscale_src=pmeinfo->tcpopt_info[KNI_DIR_C2S].wnscal; - fake_client->wscale_dst=pmeinfo->tcpopt_info[KNI_DIR_S2C].wnscal; - fake_client->sack_src=pmeinfo->tcpopt_info[KNI_DIR_C2S].sack; - fake_client->sack_dst=pmeinfo->tcpopt_info[KNI_DIR_S2C].sack; + fake_client->wscale_perm = pmeinfo->tcpopt_info[KNI_DIR_C2S].wscale_perm && pmeinfo->tcpopt_info[KNI_DIR_S2C].wscale_perm; + fake_client->wscale_src=pmeinfo->tcpopt_info[KNI_DIR_C2S].wscale; + fake_client->wscale_dst=pmeinfo->tcpopt_info[KNI_DIR_S2C].wscale; + fake_client->sack_src=pmeinfo->tcpopt_info[KNI_DIR_C2S].sack_perm; + fake_client->sack_dst=pmeinfo->tcpopt_info[KNI_DIR_S2C].sack_perm; fake_client->timestamps_src=pmeinfo->tcpopt_info[KNI_DIR_C2S].timestamps; fake_client->timestamps_dst=pmeinfo->tcpopt_info[KNI_DIR_S2C].timestamps; @@ -1227,10 +1203,11 @@ int tcprepair_get_state(int curdir,const struct layer_addr* addr,struct kni_tcp_ fake_server->ack=ntohl(tcphdr->th_seq); fake_server->mss_src=pmeinfo->tcpopt_info[KNI_DIR_S2C].mss; fake_server->mss_dst=pmeinfo->tcpopt_info[KNI_DIR_C2S].mss; - fake_server->wscale_src=pmeinfo->tcpopt_info[KNI_DIR_S2C].wnscal; - fake_server->wscale_dst=pmeinfo->tcpopt_info[KNI_DIR_C2S].wnscal; - fake_server->sack_src=pmeinfo->tcpopt_info[KNI_DIR_S2C].sack; - fake_server->sack_dst=pmeinfo->tcpopt_info[KNI_DIR_C2S].sack; + fake_server->wscale_perm=fake_client->wscale_perm; + fake_server->wscale_src=pmeinfo->tcpopt_info[KNI_DIR_S2C].wscale; + fake_server->wscale_dst=pmeinfo->tcpopt_info[KNI_DIR_C2S].wscale; + fake_server->sack_src=pmeinfo->tcpopt_info[KNI_DIR_S2C].sack_perm; + fake_server->sack_dst=pmeinfo->tcpopt_info[KNI_DIR_C2S].sack_perm; fake_server->timestamps_src=pmeinfo->tcpopt_info[KNI_DIR_S2C].timestamps; fake_server->timestamps_dst=pmeinfo->tcpopt_info[KNI_DIR_S2C].timestamps; @@ -1336,12 +1313,14 @@ int tcprepair_set_state(int sk,struct kni_tcp_state* tcp,struct sockaddr* client } } - - - opts[onr].opt_code = TCPOPT_WINDOW; - opts[onr].opt_val = tcp->wscale_dst+ (tcp->wscale_src<< 16); - onr++; - + //rfc7323 page8: both sides MUST send Window Scale options in their <SYN> segments to enable window scaling in either direction. + //The value 'shift.cnt' MAY be zero (offering to scale, while applying a scale factor of 1 to the receive window). + if(tcp->wscale_perm) + { + opts[onr].opt_code = TCPOPT_WINDOW; + opts[onr].opt_val = tcp->wscale_dst+ (tcp->wscale_src<< 16); + onr++; + } opts[onr].opt_code = TCPOPT_MAXSEG; opts[onr].opt_val = (tcp->mss_src<tcp->mss_dst)?tcp->mss_src:tcp->mss_dst; |
