address_t now works

This commit is contained in:
wangyu- 2018-07-17 11:33:02 -05:00
parent bec9c95999
commit 736c3f46b6
7 changed files with 300 additions and 67 deletions

@ -137,6 +137,42 @@ void address_t::to_str(char * s)
//return res;
}
char* address_t::get_ip()
{
char ip_addr[max_addr_len];
static char s[max_addr_len];
const char * ret=0;
if(get_type()==AF_INET6)
{
ret=inet_ntop(AF_INET6, &inner.ipv6.sin6_addr, ip_addr,max_addr_len);
}
else if(get_type()==AF_INET)
{
ret=inet_ntop(AF_INET, &inner.ipv4.sin_addr, ip_addr,max_addr_len);
}
else
{
assert(0==1);
}
if(ret==0) //NULL on failure
{
mylog(log_error,"inet_ntop failed\n");
myexit(-1);
}
ip_addr[max_addr_len-1]=0;
if(get_type()==AF_INET6)
{
sprintf(s,"[%s]",ip_addr);
}else
{
sprintf(s,"%s",ip_addr);
}
return s;
}
int address_t::from_sockaddr(sockaddr * addr,socklen_t slen)
{
memset(&inner,0,sizeof(inner));

@ -142,6 +142,38 @@ struct address_t //TODO scope id
return -1;
}
inline u32_t get_port()
{
u32_t type=get_type();
switch(type)
{
case AF_INET:
return ntohs(inner.ipv4.sin_port);
case AF_INET6:
return ntohs(inner.ipv6.sin6_port);
default:
assert(0==1);
}
return -1;
}
inline void set_port(int port)
{
u32_t type=get_type();
switch(type)
{
case AF_INET:
inner.ipv4.sin_port=htons(port);
break;
case AF_INET6:
inner.ipv6.sin6_port=htons(port);
break;
default:
assert(0==1);
}
return ;
}
bool operator == (const address_t &b) const
{
//return this->data==b.data;
@ -149,6 +181,8 @@ struct address_t //TODO scope id
}
int new_connected_udp_fd();
char* get_ip();
};
const int max_data_len=1800;

125
main.cpp

@ -55,25 +55,50 @@ int client_on_timer(conn_info_t &conn_info) //for client. called when a timer is
u32_t new_ip=0;
if(!force_source_ip&&get_src_adress(new_ip,remote_ip_uint32,remote_port)==0)
address_t new_addr;
//u32_t new_ip=0;
if(!force_source_ip)
{
if(get_src_adress2(new_addr,remote_addr)!=0)
{
mylog(log_warn,"get_src_adress() failed\n");
return -1;
}
//source_addr=new_addr;
//source_addr.set_port(0);
mylog(log_info,"source_addr is now %s\n",new_addr.get_ip());
if(new_addr.get_type()==AF_INET)
{
send_info.src_ip=new_addr.inner.ipv4.sin_addr.s_addr;
}
else
{
assert(0==1);
}
/*
if(new_ip!=source_ip_uint32)
{
mylog(log_info,"source ip changed from %s to ",my_ntoa(source_ip_uint32));
log_bare(log_info,"%s\n",my_ntoa(new_ip));
source_ip_uint32=new_ip;
send_info.src_ip=new_ip;
}
}
}*/
if (source_port == 0)
{
send_info.src_port = client_bind_to_a_new_port(bind_fd,local_ip_uint32);
}
else
{
send_info.src_port = source_port;
new_addr=source_addr;
}
if (force_source_port == 0)
{
send_info.src_port = client_bind_to_a_new_port2(bind_fd,new_addr);
}
else
{
send_info.src_port = source_addr.get_port();
}
if (raw_mode == mode_icmp)
@ -827,6 +852,7 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
return 0;
}
/*
struct sockaddr_in remote_addr_in={0};
socklen_t slen = sizeof(sockaddr_in);
@ -835,7 +861,11 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
remote_addr_in.sin_port = htons(remote_port);
remote_addr_in.sin_addr.s_addr = remote_ip_uint32;
int new_udp_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (new_udp_fd < 0) {
mylog(log_warn, "[%s]create udp_fd error\n",ip_port);
return -1;
@ -850,7 +880,14 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
mylog(log_warn, "udp fd connect fail\n");
close(new_udp_fd);
return -1;
}*/
int new_udp_fd=remote_addr.new_connected_udp_fd();
if (new_udp_fd < 0) {
mylog(log_warn, "[%s]new_connected_udp_fd() failed\n",ip_port);
return -1;
}
struct epoll_event ev;
fd64_t new_udp_fd64 = fd_manager.create(new_udp_fd);
@ -861,7 +898,7 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
ev.data.u64 = new_udp_fd64;
ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, new_udp_fd, &ev);
int ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, new_udp_fd, &ev);
if (ret != 0) {
mylog(log_warn, "[%s]add udp_fd error\n",ip_port);
@ -1068,12 +1105,13 @@ int client_event_loop()
u32_t dest_ip;
string if_name_string;
string hw_string;
assert(remote_addr.get_type()==AF_INET);
if(retry_on_error==0)
{
if(find_lower_level_info(remote_ip_uint32,dest_ip,if_name_string,hw_string)!=0)
if(find_lower_level_info(remote_addr.inner.ipv4.sin_addr.s_addr,dest_ip,if_name_string,hw_string)!=0)
{
mylog(log_fatal,"auto detect lower-level info failed for %s,specific it manually\n",remote_ip);
mylog(log_fatal,"auto detect lower-level info failed for %s,specific it manually\n",remote_addr.get_ip());
myexit(-1);
}
}
@ -1082,9 +1120,9 @@ int client_event_loop()
int ok=0;
while(!ok)
{
if(find_lower_level_info(remote_ip_uint32,dest_ip,if_name_string,hw_string)!=0)
if(find_lower_level_info(remote_addr.inner.ipv4.sin_addr.s_addr,dest_ip,if_name_string,hw_string)!=0)
{
mylog(log_warn,"auto detect lower-level info failed for %s,retry in %d seconds\n",remote_ip,retry_on_error_interval);
mylog(log_warn,"auto detect lower-level info failed for %s,retry in %d seconds\n",remote_addr.get_ip(),retry_on_error_interval);
sleep(retry_on_error_interval);
}
else
@ -1123,12 +1161,16 @@ int client_event_loop()
}
if(source_ip_uint32==0)
/*
address_t new_addr;
if(!force_source_ip)
{
mylog(log_info,"get_src_adress called\n");
if(retry_on_error==0)
{
if(get_src_adress(source_ip_uint32,remote_ip_uint32,remote_port)!=0)
if(get_src_adress2(new_addr,remote_addr)!=0)
{
mylog(log_fatal,"the trick to auto get source ip failed, maybe you dont have internet access\n");
myexit(-1);
@ -1139,7 +1181,7 @@ int client_event_loop()
int ok=0;
while(!ok)
{
if(get_src_adress(source_ip_uint32,remote_ip_uint32,remote_port)!=0)
if(get_src_adress2(new_addr,remote_addr)!=0)
{
mylog(log_warn,"the trick to auto get source ip failed, maybe you dont have internet access, retry in %d seconds\n",retry_on_error_interval);
sleep(retry_on_error_interval);
@ -1153,26 +1195,31 @@ int client_event_loop()
}
}
in_addr tmp;
tmp.s_addr=source_ip_uint32;
mylog(log_info,"source ip = %s\n",inet_ntoa(tmp));
else
{
new_addr=source_addr;
}
//in_addr tmp;
//tmp.s_addr=source_ip_uint32;
mylog(log_info,"source ip = %s\n",new_addr.get_ip());*/
//printf("done\n");
/*
if(try_to_list_and_bind(bind_fd,local_ip_uint32,source_port)!=0)
{
mylog(log_fatal,"bind to source_port:%d fail\n ",source_port);
myexit(-1);
}
send_info.src_port=source_port;
send_info.src_ip = source_ip_uint32;
}*/
send_info.src_port=0;
send_info.src_ip = 0;
int i, j, k;int ret;
//init_filter(source_port);
send_info.dst_ip=remote_ip_uint32;
send_info.dst_port=remote_port;
send_info.dst_ip=remote_addr.inner.ipv4.sin_addr.s_addr;
send_info.dst_port=remote_addr.get_port();
//g_packet_info.src_ip=source_address_uint32;
//g_packet_info.src_port=source_port;
@ -1188,8 +1235,8 @@ int client_event_loop()
socklen_t slen = sizeof(sockaddr_in);
//memset(&local_me, 0, sizeof(local_me));
local_me.sin_family = AF_INET;
local_me.sin_port = htons(local_port);
local_me.sin_addr.s_addr = local_ip_uint32;
local_me.sin_port = local_addr.get_type();
local_me.sin_addr.s_addr = local_addr.inner.ipv4.sin_addr.s_addr;
if (bind(udp_fd, (struct sockaddr*) &local_me, slen) == -1) {
@ -1404,7 +1451,12 @@ int server_event_loop()
int i, j, k;int ret;
bind_address_uint32=local_ip_uint32;//only server has bind adress,client sets it to zero
if(local_addr.inner.ipv4.sin_addr.s_addr!=0)
{
bind_addr_used=1;
bind_addr=local_addr;
}
//bind_address_uint32=local_ip_uint32;//only server has bind adress,client sets it to zero
if(lower_level)
{
@ -1433,8 +1485,8 @@ int server_event_loop()
// bzero(&temp_bind_addr, sizeof(temp_bind_addr));
temp_bind_addr.sin_family = AF_INET;
temp_bind_addr.sin_port = htons(local_port);
temp_bind_addr.sin_addr.s_addr = local_ip_uint32;
temp_bind_addr.sin_port = local_addr.get_port();
temp_bind_addr.sin_addr.s_addr = local_addr.inner.ipv4.sin_addr.s_addr;
if (bind(bind_fd, (struct sockaddr*)&temp_bind_addr, sizeof(temp_bind_addr)) !=0)
{
@ -1455,7 +1507,7 @@ int server_event_loop()
//init_raw_socket();
init_filter(local_port);//bpf filter
init_filter(local_addr.get_port());//bpf filter
epollfd = epoll_create1(0);
const int max_events = 4096;
@ -1481,7 +1533,7 @@ int server_event_loop()
u64_t begin_time=0;
u64_t end_time=0;
mylog(log_info,"now listening at %s:%d\n",my_ntoa(local_ip_uint32),local_port);
mylog(log_info,"now listening at %s\n",local_addr.get_str());
int fifo_fd=-1;
@ -1758,8 +1810,9 @@ int main(int argc, char *argv[])
mylog(log_warn,"you can run udp2raw with non-root account for better security. check README.md in repo for more info.\n");
}
local_ip_uint32=inet_addr(local_ip);
source_ip_uint32=inet_addr(source_ip);
//local_ip_uint32=inet_addr(local_ip);
//source_ip_uint32=inet_addr(source_ip);
#if ENABLE_DNS_RESOLVE
@ -1787,9 +1840,9 @@ int main(int argc, char *argv[])
#else
{
//strncpy(remote_ip,remote_address,sizeof(remote_ip)-1);
strcpy(remote_ip,remote_address);
remote_ip_uint32=inet_addr(remote_ip);
mylog(log_info,"remote_ip=[%s], make sure this is a vaild IP address\n",remote_ip);
//strcpy(remote_ip,remote_address);
//remote_ip_uint32=inet_addr(remote_ip);
mylog(log_info,"remote_ip=[%s], make sure this is a vaild IP address\n",remote_addr.get_ip());
}
#endif

@ -32,9 +32,11 @@ fd_manager_t fd_manager;
//char local_ip[100]="0.0.0.0", remote_ip[100]="255.255.255.255",source_ip[100]="0.0.0.0";//local_ip is for -l option,remote_ip for -r option,source for --source-ip
//u32_t local_ip_uint32,remote_ip_uint32,source_ip_uint32;//convert from last line.
//int local_port = -1, remote_port=-1,source_port=0;//similiar to local_ip remote_ip,buf for port.source_port=0 indicates --source-port is not enabled
address_t local_addr,remote_addr;
address_t local_addr,remote_addr,source_addr,bind_addr;
int bind_addr_used=0;
int force_source_ip=0; //if --source-ip is enabled
int force_source_port=0;
id_t const_id=0;//an id used for connection recovery,its generated randomly,it never change since its generated
@ -384,6 +386,13 @@ void process_arg(int argc, char *argv[]) //process all options
switch (opt) {
case 'l':
no_l = 0;
local_addr.from_str(optarg);
if(local_addr.get_port()==22)
{
mylog(log_fatal,"port 22 not allowed\n");
myexit(-1);
}
/*
if (strchr(optarg, ':') != 0) {
sscanf(optarg, "%[^:]:%d", local_ip, &local_port);
if(local_port==22)
@ -395,10 +404,17 @@ void process_arg(int argc, char *argv[]) //process all options
mylog(log_fatal,"invalid parameter for -l ,%s,should be ip:port\n",optarg);
myexit(-1);
}
}*/
break;
case 'r':
no_r = 0;
remote_addr.from_str(optarg);
if(remote_addr.get_port()==22)
{
mylog(log_fatal,"port 22 not allowed\n");
myexit(-1);
}
/*
if (strchr(optarg, ':') != 0) {
sscanf(optarg, "%[^:]:%d", remote_address, &remote_port);
if(remote_port==22)
@ -409,7 +425,7 @@ void process_arg(int argc, char *argv[]) //process all options
} else {
mylog(log_fatal,"invalid parameter for -r ,%s,should be ip:port\n",optarg);
myexit(-1);
}
}*/
break;
case 's':
if(program_mode==0)
@ -451,6 +467,8 @@ void process_arg(int argc, char *argv[]) //process all options
{
clear_iptables=1;
}
/////////////////////fix this later
/*
else if(strcmp(long_options[option_index].name,"source-ip")==0)
{
mylog(log_debug,"parsing long option :source-ip\n");
@ -463,7 +481,7 @@ void process_arg(int argc, char *argv[]) //process all options
mylog(log_debug,"parsing long option :source-port\n");
sscanf(optarg, "%d", &source_port);
mylog(log_info,"source: %d\n",source_port);
}
}*/
else if(strcmp(long_options[option_index].name,"raw-mode")==0)
{
for(i=0;i<mode_end;i++)
@ -701,12 +719,18 @@ void process_arg(int argc, char *argv[]) //process all options
log_bare(log_info,"key=%s ",key_string);
log_bare(log_info,"local_ip=%s ",local_ip);
log_bare(log_info,"local_addr=%s ",local_addr.get_str());
log_bare(log_info,"remote_addr=%s ",remote_addr.get_str());
if(force_source_ip||force_source_port)
log_bare(log_info,"source_addr=%s ",source_addr.get_str());
/*log_bare(log_info,"local_ip=%s ",local_ip);
log_bare(log_info,"local_port=%d ",local_port);
log_bare(log_info,"remote_address=%s ",remote_address);
log_bare(log_info,"remote_port=%d ",remote_port);
log_bare(log_info,"source_ip=%s ",source_ip);
log_bare(log_info,"source_port=%d ",source_port);
log_bare(log_info,"source_port=%d ",source_port);*/
log_bare(log_info,"socket_buf_size=%d ",socket_buf_size);
@ -868,15 +892,15 @@ void iptables_rule() // handles -a -g --gen-add --keep-rule --clear --wait-loc
{
if(raw_mode==mode_faketcp)
{
sprintf(tmp_pattern,"-s %s/32 -p tcp -m tcp --sport %d",remote_ip,remote_port);
sprintf(tmp_pattern,"-s %s/32 -p tcp -m tcp --sport %d",remote_addr.get_ip(),remote_addr.get_port());
}
if(raw_mode==mode_udp)
{
sprintf(tmp_pattern,"-s %s/32 -p udp -m udp --sport %d",remote_ip,remote_port);
sprintf(tmp_pattern,"-s %s/32 -p udp -m udp --sport %d",remote_addr.get_ip(),remote_addr.get_port());
}
if(raw_mode==mode_icmp)
{
sprintf(tmp_pattern,"-s %s/32 -p icmp",remote_ip);
sprintf(tmp_pattern,"-s %s/32 -p icmp",remote_addr.get_ip());
}
pattern=tmp_pattern;
}
@ -885,21 +909,21 @@ void iptables_rule() // handles -a -g --gen-add --keep-rule --clear --wait-loc
if(raw_mode==mode_faketcp)
{
sprintf(tmp_pattern,"-p tcp -m tcp --dport %d",local_port);
sprintf(tmp_pattern,"-p tcp -m tcp --dport %d",local_addr.get_port());
}
if(raw_mode==mode_udp)
{
sprintf(tmp_pattern,"-p udp -m udp --dport %d",local_port);
sprintf(tmp_pattern,"-p udp -m udp --dport %d",local_addr.get_port());
}
if(raw_mode==mode_icmp)
{
if(local_ip_uint32==0)
if(local_addr.inner.ipv4.sin_addr.s_addr==0)
{
sprintf(tmp_pattern,"-p icmp");
}
else
{
sprintf(tmp_pattern,"-d %s/32 -p icmp",local_ip);
sprintf(tmp_pattern,"-d %s/32 -p icmp",local_addr.get_ip());
}
}
pattern=tmp_pattern;
@ -928,19 +952,6 @@ void iptables_rule() // handles -a -g --gen-add --keep-rule --clear --wait-loc
}*/
if(auto_add_iptables_rule)
{
iptables_rule_init(pattern.c_str(),const_id,keep_rule);
if(keep_rule)
{
if(pthread_create(&keep_thread, NULL, run_keep, 0)) {
mylog(log_fatal, "Error creating thread\n");
myexit(-1);
}
keep_thread_running=1;
}
}
if(generate_iptables_rule)
{
string rule=iptables_command+"-I INPUT ";
@ -957,7 +968,23 @@ void iptables_rule() // handles -a -g --gen-add --keep-rule --clear --wait-loc
myexit(0);
}
if(auto_add_iptables_rule)
{
iptables_rule_init(pattern.c_str(),const_id,keep_rule);
if(keep_rule)
{
if(pthread_create(&keep_thread, NULL, run_keep, 0)) {
mylog(log_fatal, "Error creating thread\n");
myexit(-1);
}
keep_thread_running=1;
}
}
else
{
mylog(log_warn," -a has not been set, make sure you have added the needed iptables rules manually\n");
}
}
int unit_test()

4
misc.h

@ -78,9 +78,11 @@ union current_state_t
//extern u32_t local_ip_uint32,remote_ip_uint32,source_ip_uint32;//convert from last line.
//extern int local_port , remote_port,source_port;//similiar to local_ip remote_ip,buf for port.source_port=0 indicates --source-port is not enabled
extern address_t local_addr,remote_addr;
extern address_t local_addr,remote_addr,source_addr,bind_addr;
extern int bind_addr_used;
extern int force_source_ip; //if --source-ip is enabled
extern int force_source_port;
extern id_t const_id;//an id used for connection recovery,its generated randomly,it never change since its generated

@ -21,7 +21,7 @@ int filter_port=-1;
int disable_bpf_filter=0; //for test only,most time no need to disable this
u32_t bind_address_uint32=0;
//u32_t bind_address_uint32=0;
int lower_level=0;
int lower_level_manual=0;
@ -750,7 +750,7 @@ int recv_raw_ip(raw_info_t &raw_info,char * &payload,int &payloadlen)
}
if(bind_address_uint32!=0 &&recv_info.dst_ip!=bind_address_uint32)
if(bind_addr_used && recv_info.dst_ip!=bind_addr.inner.ipv4.sin_addr.s_addr)
{
mylog(log_trace,"bind adress doenst match, dropped\n");
//printf(" bind adress doenst match, dropped\n");
@ -1823,6 +1823,7 @@ int recv_raw(raw_info_t &raw_info,char *& payload,int & payloadlen)
}
}*/
int get_src_adress(u32_t &ip,u32_t remote_ip_uint32,int remote_port) //a trick to get src adress for a dest adress,so that we can use the src address in raw socket as source ip
{
struct sockaddr_in remote_addr_in={0};
@ -1854,7 +1855,7 @@ int get_src_adress(u32_t &ip,u32_t remote_ip_uint32,int remote_port) //a trick
struct sockaddr_in my_addr={0};
socklen_t len=sizeof(my_addr);
if(getsockname(new_udp_fd, (struct sockaddr *) &my_addr, &len)!=0) return -1;
if(getsockname(new_udp_fd, (struct sockaddr *) &my_addr, &len)!=0){close(new_udp_fd); return -1;}
ip=my_addr.sin_addr.s_addr;
@ -1863,6 +1864,26 @@ int get_src_adress(u32_t &ip,u32_t remote_ip_uint32,int remote_port) //a trick
return 0;
}
int get_src_adress2(address_t &output_addr,address_t remote_addr)
{
int new_udp_fd=remote_addr.new_connected_udp_fd();
if(new_udp_fd<0)
{
mylog(log_warn,"create udp_fd error\n");
return -1;
}
socklen_t len=sizeof(output_addr.inner);
if(getsockname(new_udp_fd, (struct sockaddr *) &output_addr.inner, &len)!=0) {close(new_udp_fd); return -1;}
assert(output_addr.get_type()==remote_addr.get_type());
close(new_udp_fd);
return 0;
}
int try_to_list_and_bind(int &fd,u32_t local_ip_uint32,int port) //try to bind to a port,may fail.
{
int old_bind_fd=fd;
@ -1902,6 +1923,46 @@ int try_to_list_and_bind(int &fd,u32_t local_ip_uint32,int port) //try to bind
}
return 0;
}
int try_to_list_and_bind2(int &fd,address_t address) //try to bind to a port,may fail.
{
int old_bind_fd=fd;
if(raw_mode==mode_faketcp)
{
fd=socket(address.get_type(),SOCK_STREAM,0);
}
else if(raw_mode==mode_udp||raw_mode==mode_icmp)
{
fd=socket(address.get_type(),SOCK_DGRAM,0);
}
if(old_bind_fd!=-1)
{
close(old_bind_fd);
}
/*struct sockaddr_in temp_bind_addr={0};
//bzero(&temp_bind_addr, sizeof(temp_bind_addr));
temp_bind_addr.sin_family = AF_INET;
temp_bind_addr.sin_port = htons(port);
temp_bind_addr.sin_addr.s_addr = local_ip_uint32;*/
if (bind(fd, (struct sockaddr*)&address.inner, address.get_len()) !=0)
{
mylog(log_debug,"bind fail\n");
return -1;
}
if(raw_mode==mode_faketcp)
{
if (listen(fd, SOMAXCONN) != 0) {
mylog(log_warn,"listen fail\n");
return -1;
}
}
return 0;
}
int client_bind_to_a_new_port(int &fd,u32_t local_ip_uint32)//find a free port and bind to it.
{
int raw_send_port=10000+get_true_random_number()%(65535-10000);
@ -1916,3 +1977,20 @@ int client_bind_to_a_new_port(int &fd,u32_t local_ip_uint32)//find a free port a
myexit(-1);
return -1;////for compiler check
}
int client_bind_to_a_new_port2(int &fd,const address_t& address)//find a free port and bind to it.
{
address_t tmp=address;
int raw_send_port=10000+get_true_random_number()%(65535-10000);
for(int i=0;i<1000;i++)//try 1000 times at max,this should be enough
{
tmp.set_port(raw_send_port);
if (try_to_list_and_bind2(fd,address)==0)
{
return raw_send_port;
}
}
mylog(log_fatal,"bind port fail\n");
myexit(-1);
return -1;////for compiler check
}

@ -13,7 +13,7 @@ extern int raw_send_fd;
extern int seq_mode;
extern int max_seq_mode;
extern int filter_port;
extern u32_t bind_address_uint32;
//extern u32_t bind_address_uint32;
extern int disable_bpf_filter;
extern int lower_level;
@ -100,9 +100,12 @@ int find_lower_level_info(u32_t ip,u32_t &dest_ip,string &if_name,string &hw);
int get_src_adress(u32_t &ip,u32_t remote_ip_uint32,int remote_port); //a trick to get src adress for a dest adress,so that we can use the src address in raw socket as source ip
int get_src_adress2(address_t &output_addr,address_t remote_addr);
int try_to_list_and_bind(int & bind_fd,u32_t local_ip_uint32,int port); //try to bind to a port,may fail.
int client_bind_to_a_new_port(int & bind_fd,u32_t local_ip_uint32);//find a free port and bind to it.
int client_bind_to_a_new_port2(int &fd,const address_t& address);
int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen);