mirror of
				https://github.com/wangyu-/UDPspeeder.git
				synced 2025-11-04 03:45:37 +08:00 
			
		
		
		
	better tuneable --fec works
This commit is contained in:
		
							
								
								
									
										18
									
								
								common.cpp
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								common.cpp
									
									
									
									
									
								
							@@ -1006,3 +1006,21 @@ u32_t sdbm(unsigned char *str,int len)
 | 
				
			|||||||
     return hash;
 | 
					     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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								common.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								common.h
									
									
									
									
									
								
							@@ -52,7 +52,7 @@ typedef int socklen_t;
 | 
				
			|||||||
#include<map>
 | 
					#include<map>
 | 
				
			||||||
#include<list>
 | 
					#include<list>
 | 
				
			||||||
#include<string>
 | 
					#include<string>
 | 
				
			||||||
 | 
					#include<vector>
 | 
				
			||||||
using  namespace std;
 | 
					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_ */
 | 
					#endif /* COMMON_H_ */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
fec_parameter_t g_fec_par;
 | 
					fec_parameter_t g_fec_par;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int debug_fec=1;
 | 
				
			||||||
//int dynamic_update_fec=1;
 | 
					//int dynamic_update_fec=1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const int encode_fast_send=1;
 | 
					const int encode_fast_send=1;
 | 
				
			||||||
@@ -314,6 +315,10 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
 | 
				
			|||||||
    			actual_data_num=best_data_num;
 | 
					    			actual_data_num=best_data_num;
 | 
				
			||||||
    			assert(best_data_num>=1&&best_data_num<=fec_par.rs_cnt);
 | 
					    			assert(best_data_num>=1&&best_data_num<=fec_par.rs_cnt);
 | 
				
			||||||
    			actual_redundant_num=fec_par.rs_par[best_data_num-1].y;
 | 
					    			actual_redundant_num=fec_par.rs_par[best_data_num-1].y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    			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);
 | 
					    				mylog(log_trace,"actual_data_num=%d actual_redundant_num=%d\n",actual_data_num,actual_redundant_num);
 | 
				
			||||||
    		}
 | 
					    		}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
					const int max_fec_packet_num=255;// this is the limitation of the rs lib
 | 
				
			||||||
extern u32_t fec_buff_num;
 | 
					extern u32_t fec_buff_num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const int rs_str_len=max_fec_packet_num*10+100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct fec_parameter_t
 | 
					struct fec_parameter_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -27,21 +28,111 @@ struct fec_parameter_t
 | 
				
			|||||||
	int timeout=8*1000;
 | 
						int timeout=8*1000;
 | 
				
			||||||
	int mode=0;
 | 
						int mode=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int rs_cnt;
 | 
						int rs_cnt=0;
 | 
				
			||||||
	struct rs_parameter_t //parameters for reed solomon
 | 
						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 x;//AKA fec_data_num  (x should be same as <index of rs_par>+1 at the moment)
 | 
				
			||||||
		unsigned char y;//fec_redundant_num
 | 
							unsigned char y;//fec_redundant_num
 | 
				
			||||||
	}rs_par[255+10];
 | 
						}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;
 | 
							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()
 | 
						rs_parameter_t get_tail()
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								misc.cpp
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								misc.cpp
									
									
									
									
									
								
							@@ -53,7 +53,8 @@ int tun_mtu=1500;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int mssfix=1;
 | 
					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)
 | 
					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.clone(tmp_par);
 | 
				
			||||||
		g_fec_par.version=version;
 | 
							g_fec_par.version=version;
 | 
				
			||||||
		g_fec_par.version++;
 | 
							g_fec_par.version++;
 | 
				
			||||||
 | 
							strcpy(rs_par_str,tmp_str);
 | 
				
			||||||
		//g_fec_data_num=a;
 | 
							//g_fec_data_num=a;
 | 
				
			||||||
		//g_fec_redundant_num=b;
 | 
							//g_fec_redundant_num=b;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -323,7 +325,13 @@ int handle_command(char *s)
 | 
				
			|||||||
			mylog(log_warn,"invaild value\n");
 | 
								mylog(log_warn,"invaild value\n");
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if(g_fec_par.mode!=a)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			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)
 | 
						else if(strncmp(s,"timeout",strlen("timeout"))==0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -381,6 +381,7 @@ int tunnel_client_event_loop()
 | 
				
			|||||||
	ev_init(&prepare_watcher,prepare_cb);
 | 
						ev_init(&prepare_watcher,prepare_cb);
 | 
				
			||||||
	ev_prepare_start(loop,&prepare_watcher);
 | 
						ev_prepare_start(loop,&prepare_watcher);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mylog(log_info,"now listening at %s\n",local_addr.get_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ev_run(loop, 0);
 | 
						ev_run(loop, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user