summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author郑超 <[email protected]>2019-02-27 13:04:40 +0800
committer郑超 <[email protected]>2019-02-27 13:04:40 +0800
commit473b7e63b3dce4c6409bb597839dae7eb73eea15 (patch)
tree7b6d4d18391d3a71e397162cd18cac79032b3bac
parentef62705899c5c7b5465c4d328e114712e5ab75b8 (diff)
parent2d57f7506223ce9c15b5c0c8b94d4eae581929a1 (diff)
Merge branch 'bugfix-downstream-timeout-on-winscale-1' into 'master'
正确处理只有一方发送wscale option的情况,删除注释掉的代码。 See merge request tango/kni!4
-rw-r--r--kni_comm.c102
-rw-r--r--kni_comm.h3
-rw-r--r--kni_entry.c11
-rw-r--r--kni_entry.h8
-rw-r--r--kni_intercept.c61
5 files changed, 48 insertions, 137 deletions
diff --git a/kni_comm.c b/kni_comm.c
index 8acb30a..aa6c141 100644
--- a/kni_comm.c
+++ b/kni_comm.c
@@ -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;
diff --git a/kni_comm.h b/kni_comm.h
index c05b523..8fbb992 100644
--- a/kni_comm.h
+++ b/kni_comm.h
@@ -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;