mirror of
https://gitee.com/willfree/http_vpn.git
synced 2026-06-03 08:16:51 +08:00
175 lines
5.2 KiB
C++
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;
|
|
} |