Files
http_vpn/http_vpn_20191209/client/Client.cpp
T
2020-02-23 20:44:48 +08:00

175 lines
5.2 KiB
C++

// simulate socks5-client. coding by wefree in 2019.08
#include "Client.h"
using namespace std;
// listen to the local port
void Client::listenLocal(){
this->sockfd=socket(AF_INET, SOCK_STREAM, 0);
/* bind the local address, so that the cliend can send to server */
bzero((char *)&(this->serv_addr), sizeof(this->serv_addr));
(this->serv_addr).sin_family = AF_INET;
(this->serv_addr).sin_addr.s_addr = htonl(INADDR_ANY);
(this->serv_addr).sin_port = htons(this->port);
// bind
int on = 1;
setsockopt(this->sockfd , SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)) ;
while( bind(this->sockfd, (struct sockaddr *) &(this->serv_addr), sizeof(this->serv_addr)) < 0){
sleep(1) ;
cout << "bind fail" << endl ;
};
listen(this->sockfd,10);
};
// listen to the local port
void Client::ndn_listen_local(string prefix){
this->listenLocal() ;
this->mndn_socket.listen(prefix.data()) ;
}
// waiting for the local port's connection
int Client::acceptLocal(){
int newsockfd;
struct sockaddr_in cli_addr;
int cli_len=sizeof(cli_addr);
cout<<"Waitting connection [client] ..."<<endl;
newsockfd = accept(this->sockfd, (struct sockaddr *) &cli_addr,
(socklen_t *)&cli_len);
// error
while(newsockfd<0){
cout<<"can't accept from local address"<<endl;
close(this->sockfd);
this->listenLocal();
newsockfd = accept(this->sockfd, (struct sockaddr *) &cli_addr,
(socklen_t *)&cli_len);
}
cout<<"Acceptted a connection [client]"<<endl;
return newsockfd;
};
// connect to the socks5-server
void Client::ndn_connSockes5Server(Ndn_socket &ndn_socket , string new_prefix){
cout << "new_prefix : " << new_prefix << endl ;
// 发送client_prefix
ndn_socket.write(new_prefix) ;
char buff[1000] ;
memset(buff, 0 , 1000) ;
// 接收server_prefix
ndn_socket.read(buff,1000) ;
string server_prefix=buff;
cout<<"server_prefix: "<<server_prefix<<endl;
ndn_socket.set_daddr(buff) ;
cout << "new client ndnsocket's daddr :" << ndn_socket.get_daddr() << endl ;
}
// data transmission shake
void Client::ndn_transData(Ndn_socket &ndn_socket , int newsockfd){
printf("Data transmission is beginning.\n");
// cout << "newsockfd's daddr :" << ndn_socket.get_daddr() << endl ;
void* sockfds[2] = {&ndn_socket,&newsockfd};
pthread_t ptid1 , ptid2 ;
pthread_create(&ptid1 , NULL , ndn_thread1 , sockfds) ;
pthread_create(&ptid2 , NULL , ndn_thread2 , sockfds) ;
pthread_join(ptid1 , NULL) ;
pthread_join(ptid2 , NULL) ;
cout<<"child process exit()"<<endl;
// close the fd in the son process
close(this->sockfd);
ndn_socket.close() ;
// exit the son process
exit(0);
}
// forever listenner function
void Client::ndn_forever(){
while(true){
int newsockfd = this->acceptLocal();
string new_prefix = this->get_newprefix();
pid_t fpid1;
while ( ( fpid1 = fork() ) < 0 ){
cout << "create child process failled. Retry..." << endl;
}
if ( 0 == fpid1 ) { // child process
cout<<"child process beginning: "<<endl;
Ndn_socket ndn_socket ;
ndn_socket.listen(new_prefix.data()) ;
ndn_socket.set_daddr(base_server_prefix.data()) ;
cout << "ini daddr :" << ndn_socket.get_daddr() << endl ;
cout << "create ndn_socket in child process" << endl ;
ndn_connSockes5Server(ndn_socket, new_prefix) ;
ndn_transData(ndn_socket, newsockfd) ;
}else{
// close the fds in main process
close(newsockfd);
}
}
}
// server start
void Client::start(){
this->ndn_listen_local(base_listen_prefix.data()) ;
this->ndn_forever() ;
close(this->sockfd) ;
};
// get a new prefix based on the listen prefix
string Client::get_newprefix(){
return (listen_prefix+to_string(p_port_seq++)) ;
// if(listen_prefix.at(listen_prefix.size()-1) != '/'){
// return (listen_prefix+"/"+to_string(p_port_seq++)) ;
// }else{
// return (listen_prefix+to_string(p_port_seq++)) ;
// }
}
// transfer data from local port to socks5-server
void *Client::ndn_thread1(void *val){
Ndn_socket *ndn_socketp = *((Ndn_socket**)val) ;
int remote_sockfd = **((int**)val + 1) ;
char *data=new char[MAX_SIZE];
int datalen;
int send_len = 0 ;
while(true){
datalen=recv(remote_sockfd, data, MAX_SIZE, 0);
cout << "**************recv from browser_sock datalen = " << datalen << endl ;
if (datalen <= 0) {
break;
}else{
send_len = ndn_socketp->write(data, datalen) ;
cout << "***************send to ndn_socket len = " << send_len << endl ;
}
}
cout << ">>>>>>>>>>>>>>>>>>>>thread1 end" << endl ;
delete data;
ndn_socketp->close() ;
cout << ">>>>>>>>>>>>>>>>>>>>ndn_socket closed" << endl ;
close(remote_sockfd) ;
return NULL;
}
// transfer data form socks5-server to local port
void *Client::ndn_thread2(void *val){
Ndn_socket *ndn_socketp = *((Ndn_socket**)val) ;
int remote_sockfd = **((int**)val + 1) ;
char *data=new char[MAX_SIZE];
int datalen;
int send_len = 0 ;
while(true){
datalen = ndn_socketp->read(data , MAX_SIZE) ;
cout << "**************recv from ndn_socket datalen = " << datalen << endl ;
if (datalen<= 0) {
break ;
}else{ // send to remote server
send_len = send(remote_sockfd, data, datalen, 0) ;
cout << "************send to browser_sockfd len = " << send_len << endl ;
}
}
cout << ">>>>>>>>>>>>>>>>>>>>thread2 end" << endl ;
delete data;
ndn_socketp->close() ;
close(remote_sockfd) ;
return NULL;
}