better tuneable --fec works

This commit is contained in:
wangyu- 2018-08-05 12:55:07 -05:00
parent 489805d90e
commit 25da3a2b03
6 changed files with 133 additions and 8 deletions

View File

@ -1006,3 +1006,21 @@ u32_t sdbm(unsigned char *str,int len)
return hash;
}
vector<string> string_to_vec(const char * s,const char * sp) {
vector<string> res;
string str=s;
char *p = strtok ((char *)str.c_str(),sp);
while (p != NULL)
{
res.push_back(p);
//printf ("%s\n",p);
p = strtok(NULL, sp);
}
/* for(int i=0;i<(int)res.size();i++)
{
printf("<<%s>>\n",res[i].c_str());
}*/
return res;
}

View File

@ -52,7 +52,7 @@ typedef int socklen_t;
#include<map>
#include<list>
#include<string>
#include<vector>
using namespace std;
@ -548,4 +548,6 @@ struct lru_collector_t:not_copy_able_t
};
vector<string> string_to_vec(const char * s,const char * sp) ;
#endif /* COMMON_H_ */

View File

@ -20,6 +20,7 @@
fec_parameter_t g_fec_par;
int debug_fec=1;
//int dynamic_update_fec=1;
const int encode_fast_send=1;
@ -314,7 +315,11 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
actual_data_num=best_data_num;
assert(best_data_num>=1&&best_data_num<=fec_par.rs_cnt);
actual_redundant_num=fec_par.rs_par[best_data_num-1].y;
mylog(log_trace,"actual_data_num=%d actual_redundant_num=%d\n",actual_data_num,actual_redundant_num);
if(debug_fec)
mylog(log_debug,"actual_data_num=%d actual_redundant_num=%d len=%d\n",actual_data_num,actual_redundant_num,blob_encode.get_shard_len(actual_data_num,0));
else
mylog(log_trace,"actual_data_num=%d actual_redundant_num=%d\n",actual_data_num,actual_redundant_num);
}
assert(blob_encode.output(actual_data_num,blob_output,fec_len)==0);

View File

@ -18,6 +18,7 @@ const u32_t anti_replay_buff_size=30000;//can be set very large
const int max_fec_packet_num=255;// this is the limitation of the rs lib
extern u32_t fec_buff_num;
const int rs_str_len=max_fec_packet_num*10+100;
struct fec_parameter_t
{
@ -27,21 +28,111 @@ struct fec_parameter_t
int timeout=8*1000;
int mode=0;
int rs_cnt;
int rs_cnt=0;
struct rs_parameter_t //parameters for reed solomon
{
unsigned char x;//AKA fec_data_num (x should be same as <index of rs_par>+1 at the moment)
unsigned char y;//fec_redundant_num
}rs_par[255+10];
int rs_from_str(char * s)
int rs_from_str(char * s)//todo inefficient
{
vector<string> str_vec=string_to_vec(s,",");
if(str_vec.size()<1) return -1;
vector<rs_parameter_t> par_vec;
for(int i=0;i<(int)str_vec.size();i++)
{
rs_parameter_t tmp_par;
string &tmp_str=str_vec[i];
int x,y;
if(sscanf((char *)tmp_str.c_str(),"%d:%d",&x,&y)!=2)
{
mylog(log_warn,"failed to parse [%s]\n",tmp_str.c_str());
return -1;
}
if(x<1||y<1||x+y>max_fec_packet_num)
{
mylog(log_warn,"invaild value x=%d y=%d\n",x,y);
return -1;
}
tmp_par.x=x;
tmp_par.y=y;
par_vec.push_back(tmp_par);
}
assert(par_vec.size()==str_vec.size());
for(int i=1;i<(int)par_vec.size();i++)
{
if(par_vec[i].x<=par_vec[i-1].x)
{
mylog(log_warn,"error in [%s], x in x:y should be in ascend order\n",s);
return -1;
}
int now_x=par_vec[i].x;
int now_y=par_vec[i].y;
int pre_x=par_vec[i-1].x;
int pre_y=par_vec[i-1].y;
double now_ratio=double(par_vec[i].y)/par_vec[i].x;
double pre_ratio=double(par_vec[i-1].y)/par_vec[i-1].x;
if(pre_ratio<now_ratio)
{
mylog(log_warn,"%d/%d < %d/%d ,not suggested\n",pre_y,pre_x,now_y,now_x);
}
}
{ //special treatment for first parameter
int x=par_vec[0].x;
int y=par_vec[0].y;
for(int i=1;i<=x;i++)
{
rs_par[i-1].x=i;
rs_par[i-1].y=y;
}
}
for(int i=1;i<(int)par_vec.size();i++)
{
int now_x=par_vec[i].x;
int now_y=par_vec[i].y;
int pre_x=par_vec[i-1].x;
int pre_y=par_vec[i-1].y;
rs_par[now_x-1].x=now_x;
rs_par[now_x-1].y=now_y;
double k= double(now_y-pre_y)/double(now_x-pre_x);
for(int j=pre_x+1;j<=now_x-1;j++)
{
int in_x=j;
int in_y= double(pre_y) + double(in_x-pre_x)*k+ 0.9999;// round to upper
if(in_x+in_y>max_fec_packet_num)
{
in_y=max_fec_packet_num-in_x;
assert(in_y>=0&&in_y<=max_fec_packet_num);
}
rs_par[in_x-1].x=in_x;
rs_par[in_x-1].y=in_y;
}
}
rs_cnt=par_vec[par_vec.size()-1].x;
return 0;
}
char *rs_to_str()
char *rs_to_str()//todo inefficient
{
return 0;
static char res[rs_str_len];
string tmp_string;
char tmp_buf[100];
assert(rs_cnt>=1);
for(int i=0;i<rs_cnt;i++)
{
sprintf(tmp_buf,"<%d,%d> ",int(rs_par[i].x),int(rs_par[i].y));
tmp_string+=tmp_buf;
}
strcpy(res,tmp_string.c_str());
return res;
}
rs_parameter_t get_tail()

View File

@ -53,7 +53,8 @@ int tun_mtu=1500;
int mssfix=1;
char rs_par_str[max_fec_packet_num*10+100];
char rs_par_str[rs_str_len];
int from_normal_to_fec(conn_info_t & conn_info,char *data,int len,int & out_n,char **&out_arr,int *&out_len,my_time_t *&out_delay)
@ -289,6 +290,7 @@ int handle_command(char *s)
g_fec_par.clone(tmp_par);
g_fec_par.version=version;
g_fec_par.version++;
strcpy(rs_par_str,tmp_str);
//g_fec_data_num=a;
//g_fec_redundant_num=b;
}
@ -323,7 +325,13 @@ int handle_command(char *s)
mylog(log_warn,"invaild value\n");
return -1;
}
g_fec_par.mode=a;
if(g_fec_par.mode!=a)
{
g_fec_par.mode=a;
assert(g_fec_par.rs_from_str(rs_par_str)==0); //re parse rs_par_str,not necessary at the moment, for futher use
g_fec_par.version++;
}
}
else if(strncmp(s,"timeout",strlen("timeout"))==0)
{

View File

@ -381,6 +381,7 @@ int tunnel_client_event_loop()
ev_init(&prepare_watcher,prepare_cb);
ev_prepare_start(loop,&prepare_watcher);
mylog(log_info,"now listening at %s\n",local_addr.get_str());
ev_run(loop, 0);