mirror of
https://gitee.com/willfree/http_vpn.git
synced 2026-06-03 08:16:51 +08:00
socks5_demo及http_vpn项目
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# http-vpn ("http-ndn-http")
|
||||
运行环境:
|
||||
1、安装NFD
|
||||
2、配置:
|
||||
$ sudo vim /usr/local/etc/ndn/nfd.conf
|
||||
查找到以下行:
|
||||
cs_unsolicited_policy XXX (XXX表示任意值)
|
||||
改为:
|
||||
cs_unsolicited_policy admit-local
|
||||
3、重启NFD
|
||||
$ nfd-stop
|
||||
$ nfd-start
|
||||
|
||||
运行方法:
|
||||
1、打开client:
|
||||
(1)进入client文件夹
|
||||
(2)$ make
|
||||
(3)$ ./client -s /aaa/nfd/vpn/server -c /aaa/nfd/vpn/client
|
||||
|
||||
2、打开server
|
||||
(1)进入server文件夹
|
||||
(2)$ make
|
||||
(3)$ ./server -s /aaa/nfd/vpn/server
|
||||
|
||||
测试方法:
|
||||
1、命令行:
|
||||
curl -v --socks5 127.0.0.1:8888 https://www.baidu.com
|
||||
curl -v --socks5 127.0.0.1:8888 https://dlie.sogoucdn.com/se/sogou_explorer_8.6_0903.exe -o test.exe
|
||||
http://mirrors.huaweicloud.com/ubuntukylin/ubuntukylin-19.04-enhanced-amd64.iso
|
||||
|
||||
2、浏览器:
|
||||
设置浏览器socks代理端口为8888
|
||||
|
||||
已经修复的bug或做出的改进:
|
||||
1、ctrl+c终止程序之后bind不通的问题;
|
||||
2、修改了接收函数里面的数据存储数组的定义方式【new方式分配】;
|
||||
3、将原来的r_queue升级为QueuePool,使得数据段顺序接收;
|
||||
4、2019.12.04 将buff_size调整到8000,无内存溢出;
|
||||
5、2019.12.05 ndn_socket可以接收不同地址的数据(重置QueuePool的wantSeq),
|
||||
也可以向不同地址发送数据(重置本身的seq属性);
|
||||
6、2019.12.05 在使用curl命令请求百度页面时概率随机性请求到;
|
||||
测试情况:握手阶段请求到的协议信息是数据传输前建立ccn_p2p连接发送的消息'/aaa/nfd/vpn/client0';
|
||||
推测原因:
|
||||
1.1 兴趣包前缀混乱:
|
||||
client端的ndn_socket的预兴趣包声明周期较长,这个预兴趣包有一定概率发送到server端
|
||||
新建的ndn_socket建立的兴趣监听中。
|
||||
1.2 或ccn_p2p的read()函数出现BUG:
|
||||
或r_queue中读取数据之后进行rev_n操作这两个操作不是原子性质的操作,
|
||||
导致server方接收数据之后立即进行再次读取数据,会将原来已经读过的数据再次读取,
|
||||
不过这种猜测的问题在于,server方进行协议握手的ndn_socket并非是原来接收prefix的ndn_socket。。。
|
||||
1.3 改造问题
|
||||
由于我们在发送数据段的时候编号进行了回卷,即同一个ndn_socket发送的前后两个数据,如果是发送给两个ndn_socket目的地址的话,这两个数据的预兴趣包及数据包的名称是一致的。这出现了冲突。
|
||||
解决方法:
|
||||
first try
|
||||
如果是1.1的错误,那末错误出现的最大可能是因为“最长前缀匹配原则”,由于'/aaa/nfd/vpn/server0'和
|
||||
'/aaa/nfd/vpn/server'对'/aaa/nfd/vpn/client0'发出的预兴趣包'/aaa/nfd/vpn/server'的匹配长度一致,因此两个ndn_socket都可能接收到缓存中的兴趣包。
|
||||
这里作如下改进以避免以上问题,设置主监听ndn_socket的兴趣前缀为'/aaa/nfd/vpn/client_base'和'/aaa/nfd/vpn/server_base',以使得前缀匹配更加精准。
|
||||
failed。
|
||||
second try
|
||||
直接写死主监听的兴趣前缀:/server_base /client_base
|
||||
【当然这么搞在参数意义上看不大通顺,先这么测试一把】
|
||||
failed。成功验证了不是前缀的问题。
|
||||
将代码回卷到first try,来保证参数意义的合理性。
|
||||
thrid try
|
||||
根据1.3的改造问题所述。
|
||||
我们可以在修改特定ndn_socket目的地址之后,不仅将该特定ndn_socket的seq重置为0,并将其start_ts进行重置,以保证后续的数据的预兴趣包Block字段及数据段的命名,均不与之前产生的数据发生冲突。
|
||||
success.
|
||||
|
||||
尚未解决bug:
|
||||
1、ndn_p2p中的丢包问题的解决(需要进行丢包测试方法的设计);
|
||||
@@ -0,0 +1,177 @@
|
||||
#include<iostream>
|
||||
#include "PriorQueue.h"
|
||||
using namespace std;
|
||||
|
||||
PriorQueue::PriorQueue(){
|
||||
//设置默认参数
|
||||
this->headSeq=0;
|
||||
this->count=0;
|
||||
this->dataTail=0;
|
||||
this->maxNum=1;
|
||||
// 根据maxNum初始化dataPriorQueue
|
||||
this->dataPriorQueue.resize(this->maxNum);
|
||||
// 初始化条件锁、互斥锁
|
||||
// pthread_cond_init(&full_cond, NULL) ;
|
||||
// pthread_mutex_init(&mutex , NULL) ;
|
||||
}
|
||||
|
||||
PriorQueue::~PriorQueue(){
|
||||
}
|
||||
|
||||
// 设置头序列号
|
||||
void PriorQueue::setHeadSeq(unsigned int seqFirst){
|
||||
this->headSeq=seqFirst;
|
||||
}
|
||||
|
||||
// 获取头序列号
|
||||
unsigned int PriorQueue::getHeadSeq(){
|
||||
return this->headSeq;
|
||||
}
|
||||
|
||||
// 设置所属数据包总长度
|
||||
void PriorQueue::setDataLen(unsigned int datalen){
|
||||
this->datalen=datalen;
|
||||
}
|
||||
|
||||
// 获取所属数据包总长度
|
||||
unsigned int PriorQueue::getDataLen(){
|
||||
return this->datalen;
|
||||
}
|
||||
|
||||
// 设置队列最大容量
|
||||
void PriorQueue::setMaxNum(int seq_n){
|
||||
this->maxNum=seq_n;
|
||||
// 根据maxNum初始化dataPriorQueue
|
||||
this->dataPriorQueue.resize(this->maxNum);
|
||||
}
|
||||
|
||||
// 获取队列最大容量
|
||||
int PriorQueue::getMaxNum(){
|
||||
return this->maxNum;
|
||||
}
|
||||
|
||||
// 设置最后一个数据段的长度
|
||||
void PriorQueue::setDataTail(int dataTail){
|
||||
this->dataTail=dataTail;
|
||||
}
|
||||
|
||||
// 获取最后一个数据段的长度
|
||||
int PriorQueue::getDataTail(){
|
||||
return this->dataTail;
|
||||
}
|
||||
|
||||
// 解析数据段
|
||||
int PriorQueue::parseData(const char* dataSeg,int len,char* rawdata){
|
||||
unsigned int seq;
|
||||
unsigned int seq_first;
|
||||
unsigned int datap_len;
|
||||
// cout<<"szof(dataSeg): "<<sizeof(dataSeg)<<endl;
|
||||
// cout<<"strlen(dataSeg): "<<strlen(dataSeg)<<endl;
|
||||
// cout<<"**********the parse result is: ***********"<<endl;
|
||||
// rawdata=(char*)malloc((len-HEAD_LEN)*sizeof(char));
|
||||
memcpy(&seq,&dataSeg[0],4);
|
||||
// cout<<"seq: "<<seq<<endl;
|
||||
memcpy(&seq_first,&dataSeg[4],4);
|
||||
// cout<<"seq_first: "<<seq_first<<endl;
|
||||
memcpy(&datap_len,&dataSeg[8],4);
|
||||
// cout<<"datap_len: "<<datap_len<<endl;
|
||||
if(this->count==0){
|
||||
this->setHeadSeq(seq_first); //所属数据包首序列号
|
||||
this->setDataLen(datap_len); //所属数据包的数据总长度
|
||||
int queue_capacity;
|
||||
queue_capacity=datap_len/DATASEG_SZ;
|
||||
if(datap_len%DATASEG_SZ!=0){
|
||||
queue_capacity++;
|
||||
this->setDataTail(datap_len%DATASEG_SZ);
|
||||
}
|
||||
this->setMaxNum(queue_capacity);
|
||||
}
|
||||
memcpy(rawdata,&dataSeg[12],(len-HEAD_LEN));
|
||||
// cout<<"rawdata: "<<rawdata<<endl;
|
||||
// cout<<"******************************************"<<endl;
|
||||
return seq;
|
||||
}
|
||||
|
||||
// 缓存数据段:数据段、数据段长度
|
||||
void PriorQueue::setDataSegment(const char* datas,int len){
|
||||
char data[DATASEG_SZ];
|
||||
int seq=parseData(datas,len,data);
|
||||
// 建构数据结构体
|
||||
dataSegment ds;
|
||||
ds.seq=seq;
|
||||
// cout<<"seq: "<<seq<<endl;
|
||||
// cout<<"len-headlen: "<<(len-HEAD_LEN)<<endl;
|
||||
// cout<<"strlen(data): "<<strlen(data)<<endl;
|
||||
// cout<<"data: "<<data<<endl;
|
||||
memcpy(ds.data,data,(len-HEAD_LEN));
|
||||
// 计算该数据段的相对位置
|
||||
int pos=seq-this->headSeq;
|
||||
// cout<<"pos: "<<pos<<endl;
|
||||
// 放入队列
|
||||
this->setDataSegment(ds,pos);
|
||||
}
|
||||
|
||||
void PriorQueue::setDataSegment(char* datas,int len){
|
||||
const char* datas_temp=datas;
|
||||
this->setDataSegment(datas_temp,len);
|
||||
}
|
||||
|
||||
// 缓存数据段
|
||||
void PriorQueue::setDataSegment(dataSegment ds,int pos){
|
||||
// cout<<"count: "<<count<<endl;
|
||||
// cout<<dataPriorQueue.size()<<endl;
|
||||
this->dataPriorQueue[pos]=ds;
|
||||
count++;
|
||||
// cout<<"success set"<<endl;
|
||||
}
|
||||
|
||||
// 如果数据包不满,则阻塞
|
||||
// void PriorQueue::waitfull(){
|
||||
// pthread_mutex_lock(&mutex) ;
|
||||
// while(this->count<this->maxNum) {
|
||||
// pthread_cond_wait(&full_cond , &mutex) ;
|
||||
// }
|
||||
// pthread_mutex_unlock(&mutex) ;
|
||||
// };
|
||||
|
||||
// 判断该队列是否放满了数据
|
||||
bool PriorQueue::isfull(){
|
||||
return this->count==this->getMaxNum();
|
||||
}
|
||||
|
||||
// 返回完整数据包
|
||||
char* PriorQueue::getDataPacket(){
|
||||
// cout<<"*********getDataPacket Information********"<<endl;
|
||||
// cout<<"count: "<<count<<endl;
|
||||
// cout<<"maxNum: "<<getMaxNum()<<endl;
|
||||
// cout<<"headseq: "<<getHeadSeq()<<endl;
|
||||
// cout<<"datatail: "<<getDataTail()<<endl;
|
||||
// cout<<"datalen: "<<getDataLen()<<endl;
|
||||
// cout<<"******************************************"<<endl;
|
||||
// 如果数据包不满,则阻塞
|
||||
// waitfull();
|
||||
// char* dp[QUEUE_SZ];
|
||||
char *dp;
|
||||
dp=(char*)malloc(this->datalen*sizeof(char));
|
||||
int rear=0;
|
||||
int clen=DATASEG_SZ;
|
||||
// 将数据段组合成数据包
|
||||
int i=0;
|
||||
for (i = 0; i < (this->maxNum-1);i++){
|
||||
// 打印dataPriorQueue的状态
|
||||
// cout<<"sizeof(datapq): "<<dataPriorQueue.size()<<endl;
|
||||
// cout<<dataPriorQueue[i].data<<endl;
|
||||
memcpy(&dp[rear],dataPriorQueue[i].data,clen);
|
||||
rear+=clen;
|
||||
}
|
||||
if(this->dataTail!=0){
|
||||
clen=this->dataTail;
|
||||
}
|
||||
memcpy(&dp[rear],dataPriorQueue[i].data,clen);
|
||||
rear+=dataTail;
|
||||
// 释放数据区内存
|
||||
vector<dataSegment> vtemp;
|
||||
this->dataPriorQueue.swap(vtemp);
|
||||
// cout<<"sizeof(datapq): "<<dataPriorQueue.size()<<endl;
|
||||
return dp;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#ifndef _PRIOR_QUEUE_H_
|
||||
#define _PRIOR_QUEUE_H_
|
||||
// 缓存同属于一个数据包的众多数据段的优先队列
|
||||
#include<cstring>
|
||||
#include<pthread.h>
|
||||
#include<vector>
|
||||
#define QUEUE_SZ 8000000 //数据包最大长度
|
||||
#define DATASEG_SZ 8000 //数据段最大长度
|
||||
#define HEAD_LEN 12 //数据段头长度
|
||||
using namespace std;
|
||||
|
||||
// 定义数据段结构体
|
||||
struct dataSegment{
|
||||
unsigned int seq; //该数据段的序列号
|
||||
char data[DATASEG_SZ]; //数据段信息
|
||||
};
|
||||
|
||||
class PriorQueue{
|
||||
public:
|
||||
PriorQueue();
|
||||
~PriorQueue();
|
||||
// 参数存取区
|
||||
void setHeadSeq(unsigned int seqFirst);
|
||||
unsigned int getHeadSeq();
|
||||
void setDataLen(unsigned int datalen);
|
||||
unsigned int getDataLen();
|
||||
void setMaxNum(int seq_n);
|
||||
int getMaxNum();
|
||||
void setDataTail(int dataTail);
|
||||
int getDataTail();
|
||||
// 将一个字符串解析,
|
||||
// 并根据序号差将当前数据段放置在相应位置
|
||||
void setDataSegment(char* datas,int len);
|
||||
void setDataSegment(const char* datas,int len);
|
||||
void setDataSegment(dataSegment ds,int pos);
|
||||
// 等待所有数据段到达
|
||||
void waitfull();
|
||||
// 将所有数据段合并成数据包进行返回
|
||||
char* getDataPacket();
|
||||
// 判断该队列是否放满数据
|
||||
bool isfull();
|
||||
|
||||
protected:
|
||||
// 标记该队列当前存储的数据包的首序列号seq_first
|
||||
unsigned int headSeq;
|
||||
// 标记该数据包的总长度
|
||||
unsigned int datalen;
|
||||
//标记该队列的结构体最大个数/分包数目seq_n
|
||||
int maxNum;
|
||||
// 标记最后一个数据段的长度
|
||||
int dataTail;
|
||||
//标志已经存入的数据段个数
|
||||
int count;
|
||||
// 存储数据段结构体的容器(vector)
|
||||
vector<dataSegment> dataPriorQueue;
|
||||
// vector<int> dataPriorQueue;
|
||||
// 数据锁:
|
||||
// 对可能在线程之间读写冲突的共享数据进行加锁。
|
||||
// pthread_cond_t full_cond ; //条件锁
|
||||
// pthread_mutex_t mutex ; //互斥锁
|
||||
|
||||
private:
|
||||
int parseData(const char* dataSeg,int len,char* rawdata);
|
||||
};
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,169 @@
|
||||
#include<iostream>
|
||||
#include "QueuePool.h"
|
||||
using namespace std;
|
||||
|
||||
QueuePool::QueuePool(){
|
||||
this->wantSeq=0;
|
||||
this->flag_head=0;
|
||||
// 初始化条件锁、互斥锁
|
||||
// pthread_cond_init(&full_cond, NULL) ;
|
||||
// pthread_mutex_init(&mutex , NULL) ;
|
||||
}
|
||||
|
||||
QueuePool::~QueuePool(){
|
||||
}
|
||||
|
||||
// 设置wantSeq
|
||||
void QueuePool::setWantSeq(unsigned int wantSeq){
|
||||
this->wantSeq=wantSeq;
|
||||
}
|
||||
|
||||
// 设置wantSeq
|
||||
void QueuePool::setWantSeq(unsigned int lastSeq,unsigned int seq_n){
|
||||
this->wantSeq=(lastSeq+seq_n);
|
||||
}
|
||||
|
||||
// 获取wantSeq
|
||||
unsigned int QueuePool::getWantSeq(){
|
||||
return this->wantSeq;
|
||||
}
|
||||
|
||||
// 重置wantSeq
|
||||
void QueuePool::initSelf(){
|
||||
// pthread_mutex_lock(&m_mutex) ;
|
||||
this->wantSeq=0;
|
||||
// pthread_mutex_unlock(&m_mutex) ;
|
||||
}
|
||||
|
||||
// 设置头部缓存队列
|
||||
void QueuePool::setHeadQueue(PriorQueue pq){
|
||||
this->headQueue=pq;
|
||||
}
|
||||
|
||||
// 将头部缓存队列的数据弹出到二级缓存队列中
|
||||
void QueuePool::moveDataPacket(){
|
||||
if(this->flag_head==0){
|
||||
cout<<"move data packet error."<<endl;
|
||||
return;
|
||||
}
|
||||
char* dataPacket;
|
||||
dataPacket=this->headQueue.getDataPacket();
|
||||
unsigned int datalen=this->headQueue.getDataLen();
|
||||
this->r_queue.push_ndata(dataPacket,(int)datalen);
|
||||
// 更新want_seq、flag_head
|
||||
int pkgn=this->headQueue.getMaxNum();
|
||||
this->setWantSeq(wantSeq,(unsigned int)pkgn);
|
||||
flag_head=0;
|
||||
}
|
||||
|
||||
// 更新头部缓存队列
|
||||
void QueuePool::updateHeadQueue(){
|
||||
if(this->flag_head==1){
|
||||
cout<<"update head queue error."<<endl;
|
||||
return;
|
||||
}
|
||||
map<unsigned int,PriorQueue>::iterator it;
|
||||
it=this->waitQueues.find(wantSeq);
|
||||
if(it!=waitQueues.end()){
|
||||
this->setHeadQueue((*it).second);
|
||||
this->flag_head=1;
|
||||
waitQueues.erase(it);
|
||||
}else{}
|
||||
}
|
||||
|
||||
// 往数据缓存池中放入一个数据段
|
||||
void QueuePool::pushDataSegment(const char* data,int len){
|
||||
// 取一个数据段的头序列号
|
||||
unsigned int seq_first;
|
||||
memcpy(&seq_first,&data[4],4);
|
||||
// 匹配头部缓存队列
|
||||
if((flag_head==1)&&(seq_first==this->headQueue.getHeadSeq())){
|
||||
this->headQueue.setDataSegment(data,len);
|
||||
// 若头部队列满了,则不断更新它
|
||||
while((flag_head==1)&&(this->headQueue.isfull())){
|
||||
this->moveDataPacket();
|
||||
this->updateHeadQueue();
|
||||
}
|
||||
}else{
|
||||
// 匹配一级缓存队列池
|
||||
map<unsigned int,PriorQueue>::iterator it;
|
||||
it=this->waitQueues.find(seq_first);
|
||||
if(it!=waitQueues.end()){
|
||||
(*it).second.setDataSegment(data,len);
|
||||
}else{
|
||||
// 该数据段是所属数据包到达的第一个数据段
|
||||
PriorQueue pq;
|
||||
pq.setDataSegment(data,len);
|
||||
// 加到头部
|
||||
if((flag_head==0)&&(wantSeq==seq_first)){
|
||||
this->setHeadQueue(pq);
|
||||
this->flag_head=1;
|
||||
// 若头部队列满了,则不断更新它
|
||||
while((flag_head==1)&&(this->headQueue.isfull())){
|
||||
this->moveDataPacket();
|
||||
this->updateHeadQueue();
|
||||
}
|
||||
}else{
|
||||
//加到map中
|
||||
// cout<<"insert the map"<<endl;
|
||||
waitQueues.insert(map<unsigned int,PriorQueue>::value_type(pq.getHeadSeq(),pq));
|
||||
}
|
||||
}
|
||||
}
|
||||
// 打印数据缓存池的当前状态。测试用
|
||||
// this->printQueuePool();
|
||||
}
|
||||
|
||||
void QueuePool::pushDataSegment(char* data,int len){
|
||||
const char* data_temp=data;
|
||||
this->pushDataSegment(data_temp,len);
|
||||
}
|
||||
|
||||
// 打印二级缓存队列的数据
|
||||
void QueuePool::printRQueue(){
|
||||
int n=this->r_queue.get_data_len();
|
||||
char data[n];
|
||||
this->r_queue.get_ndata(data,n);
|
||||
// cout<<data<<endl;
|
||||
if(n!=0){
|
||||
cout<<"r_queue_data_len: "<<n<<endl;
|
||||
cout<<"the r_queue data now is: ";
|
||||
for(int i=0;i<n;i++){
|
||||
cout<<data[i];
|
||||
}
|
||||
cout<<endl;
|
||||
}else{
|
||||
cout<<"the r_queue data now is null. "<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
// 打印整个队列池的队列状态
|
||||
void QueuePool::printQueuePool(){
|
||||
// cout<<endl<<endl;
|
||||
cout<<"*********The Queue Pool State Information********"<<endl;
|
||||
cout<<"the wantSeq is: "<<this->getWantSeq()<<endl;
|
||||
// 二级缓存队列
|
||||
cout<<"--------------------------------------------------------------------"<<endl;
|
||||
this->printRQueue();
|
||||
// 头部等待队列
|
||||
cout<<"--------------------------------------------------------------------"<<endl;
|
||||
if(this->flag_head==0){
|
||||
cout<<"the head queue of the first level queue is null."<<endl;
|
||||
}else{
|
||||
cout<<"the head queue's headSeq is: "
|
||||
<<this->headQueue.getHeadSeq()
|
||||
<<endl;
|
||||
}
|
||||
// 一级缓存队列池
|
||||
cout<<"--------------------------------------------------------------------"<<endl;
|
||||
cout<<"the first level queue map size is: "<<waitQueues.size()<<endl;
|
||||
if(waitQueues.size()!=0){
|
||||
map<unsigned int,PriorQueue>::iterator it;
|
||||
cout<<"Their headSeq(s) are: ";
|
||||
for(it=waitQueues.begin();it!=waitQueues.end();it++){
|
||||
cout<<(*it).first<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
}
|
||||
cout<<"***************************************************"<<endl;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#ifndef _PRIOR_QUEUE_POOL_H_
|
||||
#define _PRIOR_QUEUE_POOL_H_
|
||||
// 解析数据段,存放数据段进序号优先队列
|
||||
// 当要接收到的下一个数据包全部到达时,
|
||||
// 将该队列的数据包缓存入顺序缓冲队列.
|
||||
#include<string.h>
|
||||
#include<pthread.h>
|
||||
#include<map>
|
||||
#include "PriorQueue.h"
|
||||
#include "r_queue.h"
|
||||
|
||||
class QueuePool{
|
||||
public:
|
||||
QueuePool();
|
||||
~QueuePool();
|
||||
// 放入一个数据段
|
||||
void pushDataSegment(const char *data,int len);
|
||||
void pushDataSegment(char *data,int len);
|
||||
// 更新头部缓存队列
|
||||
void updateHeadQueue();
|
||||
// 将某一级缓存队列设置成头部缓存队列
|
||||
void setHeadQueue(PriorQueue pq);
|
||||
// 弹出头部缓存队列的数据
|
||||
void moveDataPacket();
|
||||
// 重置wantSeq为0
|
||||
void initSelf();
|
||||
|
||||
// 打印二级缓存队列的数据。用于测试
|
||||
void printRQueue();
|
||||
// 打印当前QueuePool的状态信息。用于测试
|
||||
void printQueuePool();
|
||||
|
||||
public:
|
||||
// 二级缓存队列。能够直接读取数据的缓存区
|
||||
R_Queue r_queue;
|
||||
|
||||
protected:
|
||||
// 当前想要拿到的数据包的首序列号
|
||||
unsigned int wantSeq;
|
||||
// 头部缓存队列是否为空的标志
|
||||
int flag_head;
|
||||
//头部缓存队列(headSeq等于want_seq的一级缓存队列)
|
||||
PriorQueue headQueue;
|
||||
// 一级缓存队列池
|
||||
map<unsigned int,PriorQueue> waitQueues;
|
||||
// 数据锁
|
||||
// pthread_cond_t _cond ; //条件锁
|
||||
// pthread_mutex_t _mutex ; //互斥锁
|
||||
|
||||
private:
|
||||
void setWantSeq(unsigned int wantSeq);
|
||||
void setWantSeq(unsigned int lastSeq, unsigned int seq_n);
|
||||
unsigned int getWantSeq();
|
||||
};
|
||||
// 设置头部缓存队列的目的是:
|
||||
// 只要它满了,就可以弹出数据到二级缓存,
|
||||
// 而不需要每次在队列池先找到want_seq,再判断
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
||||
testMain: testMain.o QueuePool.o PriorQueue.o r_queue.o
|
||||
g++ -o testMain testMain.o QueuePool.o PriorQueue.o r_queue.o
|
||||
testMain.o : testMain.cpp
|
||||
g++ -c -g testMain.cpp
|
||||
QueuePool.o: QueuePool.cpp QueuePool.h
|
||||
g++ -c -g QueuePool.cpp
|
||||
PriorQueue.o : PriorQueue.cpp PriorQueue.h
|
||||
g++ -c -g PriorQueue.cpp
|
||||
r_queue.o: r_queue.cpp r_queue.h
|
||||
g++ -c -g r_queue.cpp
|
||||
|
||||
clean :
|
||||
rm -rf *.o testMain
|
||||
|
||||
# testMain: PriorQueue.o testMain.o
|
||||
# g++ -o testMain PriorQueue.o testMain.o
|
||||
# PriorQueue.o : PriorQueue.cpp PriorQueue.h
|
||||
# g++ -c PriorQueue.cpp
|
||||
# testMain.o : testMain.cpp
|
||||
# g++ -c testMain.cpp
|
||||
|
||||
# clean :
|
||||
# rm -rf *.o testMain
|
||||
@@ -0,0 +1,164 @@
|
||||
#include <iostream>
|
||||
#include "r_queue.h"
|
||||
using namespace std;
|
||||
|
||||
R_Queue::R_Queue(){
|
||||
this->head = 0 ;
|
||||
this->rear = 0 ;
|
||||
pthread_cond_init(&has_data , NULL) ;
|
||||
pthread_cond_init(&has_space , NULL) ;
|
||||
pthread_mutex_init(&m_mutex , NULL) ;
|
||||
}
|
||||
|
||||
R_Queue::~R_Queue(){
|
||||
}
|
||||
|
||||
int R_Queue::get_head(){
|
||||
int ret = 0 ;
|
||||
pthread_mutex_lock(&m_mutex) ;
|
||||
ret = head ;
|
||||
pthread_mutex_unlock(&m_mutex) ;
|
||||
return head ;
|
||||
}
|
||||
|
||||
int R_Queue::get_rear(){
|
||||
return rear ;
|
||||
}
|
||||
|
||||
bool R_Queue::is_full(){
|
||||
return ((this->rear+1)%QUEUE_SZ == this->head) ;
|
||||
}
|
||||
|
||||
bool R_Queue::is_empty(){
|
||||
bool ret = false ;
|
||||
pthread_mutex_lock(&m_mutex) ;
|
||||
ret = (this->head == this->rear) ;
|
||||
pthread_mutex_unlock(&m_mutex) ;
|
||||
return ret ;
|
||||
}
|
||||
|
||||
char *R_Queue::get_head_p(){
|
||||
return &(buff[this->head]);
|
||||
}
|
||||
|
||||
char *R_Queue::get_rear_p(){
|
||||
return &(buff[this->rear]) ;
|
||||
}
|
||||
|
||||
// 得到所有数据的长度
|
||||
int R_Queue::get_data_len(){
|
||||
int ret = 0 ;
|
||||
pthread_mutex_lock(&m_mutex) ;
|
||||
ret = (rear - head + QUEUE_SZ)%QUEUE_SZ ;
|
||||
pthread_mutex_unlock(&m_mutex) ;
|
||||
return ret ;
|
||||
}
|
||||
|
||||
// 得到空余长度
|
||||
int R_Queue::get_free_space(){
|
||||
return (head-rear-1+QUEUE_SZ)%QUEUE_SZ ;
|
||||
}
|
||||
|
||||
// get the length of a continuous free space
|
||||
// 获得从rear开始往后的连续剩余空间的长度
|
||||
int R_Queue::get_cfree_space(){
|
||||
int space = 0 ;
|
||||
if(head <= rear ) {
|
||||
space = QUEUE_SZ - rear ;
|
||||
if(head == 0) {
|
||||
space -= 1 ;
|
||||
}
|
||||
}else{
|
||||
space = head - rear - 1 ;
|
||||
}
|
||||
return space ;
|
||||
}
|
||||
|
||||
// begin at head , get the continuous data block len in ring queue
|
||||
// 获得从head往后的连续数据段的长度
|
||||
int R_Queue::get_cdata_len(){
|
||||
int len = 0;
|
||||
if(rear < head){
|
||||
len = QUEUE_SZ - head ;
|
||||
}else{
|
||||
len = rear-head ;
|
||||
}
|
||||
return len ;
|
||||
}
|
||||
|
||||
// 增加n字节的数据
|
||||
// 如果是从空到有,则激活has_data条件锁
|
||||
int R_Queue::add_n(int n){
|
||||
bool need_signal = false ;
|
||||
pthread_mutex_lock(&m_mutex) ;
|
||||
need_signal = (head == rear) ;
|
||||
rear = (rear + n) % QUEUE_SZ ;
|
||||
pthread_mutex_unlock(&m_mutex) ;
|
||||
if(need_signal){
|
||||
pthread_cond_signal(&has_data) ;
|
||||
}
|
||||
}
|
||||
|
||||
// 减少n字节的数据
|
||||
// 如果是从满到不满,则激活has_space条件锁
|
||||
int R_Queue::rmv_n(int n){
|
||||
bool need_signal = false ;
|
||||
pthread_mutex_lock(&m_mutex) ;
|
||||
need_signal = ((rear+1)%QUEUE_SZ == head) ;
|
||||
head = (head + n) % QUEUE_SZ ;
|
||||
pthread_mutex_unlock(&m_mutex) ;
|
||||
if(need_signal){
|
||||
pthread_cond_signal(&has_space) ;
|
||||
}
|
||||
}
|
||||
|
||||
// copy n Byte data from buff to data
|
||||
// 从start开始,往后取n字节数据
|
||||
int R_Queue::get_ndata(int start , char *data ,int n ){
|
||||
//printf("&&&&&&&&&&&& = start = %d , n = %d \n",start , n );
|
||||
if(start + n >= QUEUE_SZ){
|
||||
memcpy(data,&buff[start],QUEUE_SZ-start);
|
||||
memcpy(&data[QUEUE_SZ-start],buff,n+start-QUEUE_SZ);
|
||||
}else{
|
||||
memcpy(data,&buff[start],n);
|
||||
}
|
||||
}
|
||||
|
||||
// copy n Byte data from buff to data
|
||||
// 从head开始,往后取n字节数据
|
||||
int R_Queue::get_ndata(char *data ,int n ){
|
||||
get_ndata(head , data , n) ;
|
||||
}
|
||||
|
||||
// 队列中加入n字节数据
|
||||
int R_Queue::push_ndata(const char *data , int n){
|
||||
//if(get_free_space() < n) return -1 ;
|
||||
while(get_free_space() < n ) ;
|
||||
int clen ;
|
||||
while(n > 0){
|
||||
clen = get_cfree_space() ;
|
||||
if(clen > n) clen = n;
|
||||
memcpy(&buff[rear],data,clen);
|
||||
add_n(clen);
|
||||
n -= clen ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 等待数据,若队列为空,当前进程等待在 has_data变量下
|
||||
void R_Queue::wait4data() {
|
||||
pthread_mutex_lock(&m_mutex) ;
|
||||
while(head == rear) {
|
||||
pthread_cond_wait(&has_data , &m_mutex) ;
|
||||
}
|
||||
pthread_mutex_unlock(&m_mutex) ;
|
||||
}
|
||||
|
||||
// 等待空余,若队列为满,当前进程等待在has_space变量下
|
||||
void R_Queue::wait4space() {
|
||||
pthread_mutex_lock(&m_mutex) ;
|
||||
while( (rear+1)%QUEUE_SZ == head) {
|
||||
pthread_cond_wait(&has_space , &m_mutex) ;
|
||||
}
|
||||
pthread_mutex_unlock(&m_mutex) ;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#ifndef _R_QUEUE_H_
|
||||
#define _R_QUEUE_H_
|
||||
// 针对数据包已按照发送顺序缓存得到的数据队列
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#define QUEUE_SZ 8000000 //约8MB
|
||||
|
||||
class R_Queue
|
||||
{
|
||||
public:
|
||||
R_Queue() ;
|
||||
~R_Queue();
|
||||
int get_head();
|
||||
int get_rear();
|
||||
bool is_full();
|
||||
bool is_empty();
|
||||
int add_n(int n);
|
||||
int rmv_n(int n);
|
||||
char *get_head_p();
|
||||
char *get_rear_p();
|
||||
|
||||
// 得到所有数据的长度;
|
||||
int get_data_len();
|
||||
|
||||
// begin at head , get the continuous data block len in ring queue;
|
||||
int get_cdata_len();
|
||||
|
||||
// 得到空余长度;
|
||||
int get_free_space();
|
||||
|
||||
// get the length of a continuous free space;
|
||||
int get_cfree_space();
|
||||
|
||||
// copy n Byte data from buff to data ;
|
||||
// 从start开始,往后取n字节数据;
|
||||
int get_ndata(int start , char *data ,int n );
|
||||
int get_ndata(char *data ,int n );
|
||||
|
||||
// 队列中加入n字节数据;
|
||||
int push_ndata(const char *data , int n);
|
||||
// int push_ndata(const char *data , unsigned int n);
|
||||
|
||||
// 等待数据,若队列为空,当前进程等待在 has_data变量下
|
||||
void wait4data() ;
|
||||
void wait4space() ;
|
||||
|
||||
protected:
|
||||
int rear ;
|
||||
int head ;
|
||||
char buff[QUEUE_SZ];
|
||||
pthread_cond_t has_data ; //条件锁
|
||||
pthread_cond_t has_space ;
|
||||
pthread_mutex_t m_mutex ; //互斥锁
|
||||
|
||||
private:
|
||||
/* data */
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,157 @@
|
||||
#include<iostream>
|
||||
#include<stdlib.h>
|
||||
#include<cstring>
|
||||
#include "QueuePool.h"
|
||||
#define HEAD_LEN 12
|
||||
// #define DATASEG_SZ 20 //数据段最大长度
|
||||
using namespace std;
|
||||
// 测试程序
|
||||
// 用于测试QueuePool对于数据段乱序的处理
|
||||
|
||||
// 将字符数组封装成约定格式的数据段
|
||||
int makeData(unsigned int seq,unsigned int seq_first,
|
||||
unsigned int len,char *data,int datalen,char *resultData);
|
||||
|
||||
int main(){
|
||||
// 制造数据包0:包含数据段012
|
||||
char rawData0[]="imissyou.00000.";
|
||||
char rawData1[]="imissyou.11111.";
|
||||
char rawData2[]="imissyou.2222.";
|
||||
char resultData0[15+HEAD_LEN];
|
||||
char resultData1[15+HEAD_LEN];
|
||||
char resultData2[14+HEAD_LEN];
|
||||
makeData(0,0,44,rawData0,15,resultData0);
|
||||
makeData(1,0,44,rawData1,15,resultData1);
|
||||
makeData(2,0,44,rawData2,14,resultData2);
|
||||
// 制造数据包3:包含数据段345
|
||||
char rawData3[]="imissyou.33333.";
|
||||
char rawData4[]="imissyou.44444.";
|
||||
char rawData5[]="imissyou.555.";
|
||||
char resultData3[15+HEAD_LEN];
|
||||
char resultData4[15+HEAD_LEN];
|
||||
char resultData5[13+HEAD_LEN];
|
||||
makeData(3,3,43,rawData3,15,resultData3);
|
||||
makeData(4,3,43,rawData4,15,resultData4);
|
||||
makeData(5,3,43,rawData5,13,resultData5);
|
||||
// 新建并打印QueuePool的初始状态
|
||||
QueuePool *qp= new QueuePool();
|
||||
qp->printQueuePool();
|
||||
// 按照序号420351的顺序模拟乱序数据段的接收
|
||||
// 注:此时数据段的先后顺序不仅包内乱序,
|
||||
// 而且包间乱序
|
||||
cout<<endl<<endl;
|
||||
cout<<"set data segment 4 of data packet 3: "<<endl;
|
||||
qp->pushDataSegment(resultData4,15+HEAD_LEN);
|
||||
|
||||
cout<<endl<<endl;
|
||||
cout<<"set data segment 2 of data packet 0: "<<endl;
|
||||
qp->pushDataSegment(resultData2,14+HEAD_LEN);
|
||||
|
||||
cout<<endl<<endl;
|
||||
cout<<"set data segment 0 of data packet 0: "<<endl;
|
||||
qp->pushDataSegment(resultData0,15+HEAD_LEN);
|
||||
|
||||
cout<<endl<<endl;
|
||||
cout<<"set data segment 3 of data packet 3: "<<endl;
|
||||
qp->pushDataSegment(resultData3,15+HEAD_LEN);
|
||||
|
||||
cout<<endl<<endl;
|
||||
cout<<"set data segment 5 of data packet 3: "<<endl;
|
||||
qp->pushDataSegment(resultData5,13+HEAD_LEN);
|
||||
|
||||
cout<<endl<<endl;
|
||||
cout<<"set data segment 1 of data packet 0: "<<endl;
|
||||
qp->pushDataSegment(resultData1,15+HEAD_LEN);
|
||||
|
||||
delete qp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 将数据加上首序列号等信息
|
||||
int makeData(unsigned int seq,unsigned int seq_first,
|
||||
unsigned int len,char *data,int datalen,char *resultData){
|
||||
memcpy(&resultData[0],&seq,4);
|
||||
memcpy(&resultData[4],&seq_first,4);
|
||||
memcpy(&resultData[8],&len,4);
|
||||
memcpy(&resultData[12],&data[0],datalen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// int main(){
|
||||
|
||||
// PriorQueue *pq= new PriorQueue();
|
||||
// char rawData1[]="imissyou.11111.";
|
||||
// char rawData2[]="imissyou.22222.";
|
||||
// char rawData3[]="imissyou.33333.";
|
||||
// char resultData1[8000+HEAD_LEN];
|
||||
// char resultData2[8000+HEAD_LEN];
|
||||
// char resultData3[7000+HEAD_LEN];
|
||||
// makeData(0,0,23000,rawData1,8000,resultData1);
|
||||
// makeData(1,0,23000,rawData2,8000,resultData2);
|
||||
// makeData(2,0,23000,rawData3,7000,resultData3);
|
||||
|
||||
// cout<<endl<<endl<<endl;
|
||||
// cout<<"test2"<<endl;
|
||||
// pq->setDataSegment(resultData2,8012);
|
||||
|
||||
// cout<<endl<<endl<<endl;
|
||||
// cout<<"test1"<<endl;
|
||||
// pq->setDataSegment(resultData1,8012);
|
||||
|
||||
// cout<<endl<<endl<<endl;
|
||||
// cout<<"test3"<<endl;
|
||||
// pq->setDataSegment(resultData3,7012);
|
||||
|
||||
// char *dataPacket;
|
||||
|
||||
// cout<<endl<<endl<<endl;
|
||||
// dataPacket=pq->getDataPacket();
|
||||
|
||||
// cout<<endl<<endl<<endl;
|
||||
// cout<<"dataPacket: "<<endl;
|
||||
// cout<<dataPacket<<endl;
|
||||
// cout<<&dataPacket[8000]<<endl;
|
||||
// cout<<&dataPacket[16000]<<endl;
|
||||
|
||||
// delete pq;
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// int main(){
|
||||
// // 制造数据段区
|
||||
// PriorQueue *pq= new PriorQueue();
|
||||
// char rawData1[]="imissyou.11111.";
|
||||
// char rawData2[]="imissyou.22222.";
|
||||
// char rawData3[]="imissyou.3333.";
|
||||
// char resultData1[15+HEAD_LEN];
|
||||
// char resultData2[15+HEAD_LEN];
|
||||
// char resultData3[14+HEAD_LEN];
|
||||
// makeData(0,0,44,rawData1,15,resultData1);
|
||||
// makeData(1,0,44,rawData2,15,resultData2);
|
||||
// makeData(2,0,44,rawData3,14,resultData3);
|
||||
// // 装填数据段区
|
||||
// cout<<endl<<endl<<endl;
|
||||
// cout<<"test2"<<endl;
|
||||
// pq->setDataSegment(resultData2,15+HEAD_LEN);
|
||||
|
||||
// cout<<endl<<endl<<endl;
|
||||
// cout<<"test1"<<endl;
|
||||
// pq->setDataSegment(resultData1,15+HEAD_LEN);
|
||||
|
||||
// cout<<endl<<endl<<endl;
|
||||
// cout<<"test3"<<endl;
|
||||
// pq->setDataSegment(resultData3,14+HEAD_LEN);
|
||||
|
||||
// // 组装数据包区
|
||||
// char *dataPacket;
|
||||
|
||||
// cout<<endl<<endl<<endl;
|
||||
// dataPacket=pq->getDataPacket();
|
||||
|
||||
// cout<<endl<<endl<<endl;
|
||||
// cout<<"dataPacket: "<<endl;
|
||||
// cout<<dataPacket<<endl;
|
||||
|
||||
// delete pq;
|
||||
// return 0;
|
||||
// }
|
||||
@@ -0,0 +1,36 @@
|
||||
LFLAGS := -lpthread -lpcap -lndn-cxx -lboost_system -ljsoncpp
|
||||
|
||||
main: send recv1 recv2
|
||||
|
||||
send : ndnp2p_send.o ndn_socket.o QueuePool.o PriorQueue.o r_queue.o
|
||||
g++ -o send ndnp2p_send.o ndn_socket.o QueuePool.o PriorQueue.o r_queue.o $(LFLAGS)
|
||||
|
||||
recv1 : ndnp2p_recv1.o ndn_socket.o QueuePool.o PriorQueue.o r_queue.o
|
||||
g++ -o recv1 ndnp2p_recv1.o ndn_socket.o QueuePool.o PriorQueue.o r_queue.o $(LFLAGS)
|
||||
|
||||
recv2 : ndnp2p_recv2.o ndn_socket.o QueuePool.o PriorQueue.o r_queue.o
|
||||
g++ -o recv2 ndnp2p_recv2.o ndn_socket.o QueuePool.o PriorQueue.o r_queue.o $(LFLAGS)
|
||||
|
||||
ndnp2p_recv1.o : ndnp2p_recv1.cpp
|
||||
g++ -c -g -std=c++14 ndnp2p_recv1.cpp
|
||||
|
||||
ndnp2p_recv2.o : ndnp2p_recv2.cpp
|
||||
g++ -c -g -std=c++14 ndnp2p_recv2.cpp
|
||||
|
||||
ndnp2p_send.o : ndnp2p_send.cpp
|
||||
g++ -c -g -std=c++14 ndnp2p_send.cpp
|
||||
|
||||
ndn_socket.o : ndn_socket.cpp ndn_socket.h
|
||||
g++ -c -g -std=c++14 ndn_socket.cpp
|
||||
|
||||
QueuePool.o: PriorQueuePool/QueuePool.cpp PriorQueuePool/QueuePool.h
|
||||
g++ -c -g -std=c++14 PriorQueuePool/QueuePool.cpp
|
||||
|
||||
PriorQueue.o : PriorQueuePool/PriorQueue.cpp PriorQueuePool/PriorQueue.h
|
||||
g++ -c -g -std=c++14 PriorQueuePool/PriorQueue.cpp
|
||||
|
||||
r_queue.o : PriorQueuePool/r_queue.cpp PriorQueuePool/r_queue.h
|
||||
g++ -c -g -std=c++14 PriorQueuePool/r_queue.cpp
|
||||
|
||||
clean :
|
||||
rm -rf *.o send recv1 recv2
|
||||
@@ -0,0 +1,346 @@
|
||||
#include <iostream>
|
||||
#include "ndn_socket.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ndn;
|
||||
|
||||
// 类的实例化
|
||||
Ndn_socket::Ndn_socket(){
|
||||
this->seq = 0 ;
|
||||
this->faddr = "ini_faddr";
|
||||
this->daddr = "ini_daddr";
|
||||
// 时间戳
|
||||
struct timeval start ;
|
||||
gettimeofday(&start , NULL) ;
|
||||
this->start_ts = to_string(start.tv_sec) ;
|
||||
|
||||
pthread_create(&(this->m_tid) , NULL , run, (void*)&m_face) ;
|
||||
this->state = true ;
|
||||
}
|
||||
|
||||
Ndn_socket::~Ndn_socket(){
|
||||
}
|
||||
|
||||
// 设置某特定prefix的兴趣监听
|
||||
int Ndn_socket::listen(const char *prefix){
|
||||
this->maddr = prefix ;
|
||||
//cout << "set filter " << prefix << endl ;
|
||||
m_face.setInterestFilter(prefix,
|
||||
bind(&Ndn_socket::onInterest, this, _1, _2) ,
|
||||
RegisterPrefixSuccessCallback() ,
|
||||
bind(&Ndn_socket::onRegisterFailed, this, _1, _2)) ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
// 设置要将数据推送到的目的prefix
|
||||
int Ndn_socket::set_daddr(const char * prefix){
|
||||
if(prefix!=this->daddr){
|
||||
// 向新的ndn_socket发送数据
|
||||
// 重置seq
|
||||
this->seq=0;
|
||||
// 重置start_ts => 保证后续数据名的唯一性
|
||||
// 长度无限增长是个bug,后期可优化
|
||||
this->start_ts = (this->start_ts+'0' );
|
||||
}
|
||||
this->daddr = prefix ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
// 查询要将数据推送到的目的prefix
|
||||
string Ndn_socket::get_daddr(){
|
||||
return this->daddr ;
|
||||
}
|
||||
|
||||
int Ndn_socket::write(const string& data) {
|
||||
return this->write(data.data() , data.length() , this->maddr) ;
|
||||
}
|
||||
|
||||
int Ndn_socket::write(const char * data , int len ) {
|
||||
return this->write(data , len , this->maddr) ;
|
||||
}
|
||||
|
||||
int Ndn_socket::write(const uint8_t * data , int len) {
|
||||
return this->write((char*)data, len , this->maddr) ;
|
||||
}
|
||||
|
||||
int Ndn_socket::write(const uint8_t * data , int len , string dname_base) {
|
||||
return this->write((char*)data, len , dname_base) ;
|
||||
}
|
||||
|
||||
// 给数据段加段头
|
||||
int Ndn_socket::makeData(unsigned int seq,unsigned int seq_first,
|
||||
unsigned int len,const char *data,int datalen,char *resultData){
|
||||
memcpy(&resultData[0],&seq,4);
|
||||
memcpy(&resultData[4],&seq_first,4);
|
||||
memcpy(&resultData[8],&len,4);
|
||||
memcpy(&resultData[12],&data[0],datalen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 解析数据段=>用于测试
|
||||
int Ndn_socket::parseData(char* dataSeg,int datalen,char* rawdata){
|
||||
unsigned int seq;
|
||||
unsigned int seq_first;
|
||||
unsigned int len;
|
||||
// cout<<"szof(dataSeg): "<<sizeof(dataSeg)<<endl;
|
||||
// cout<<"strlen(dataSeg): "<<strlen(dataSeg)<<endl;
|
||||
cout<<"**********the parse result is: ***********"<<endl;
|
||||
// char* data=(char*)malloc((datalen-HEAD_LEN)*sizeof(char));
|
||||
memcpy(&seq,&dataSeg[0],4);
|
||||
cout<<"seq: "<<seq<<endl;
|
||||
memcpy(&seq_first,&dataSeg[4],4);
|
||||
cout<<"seq_first: "<<seq_first<<endl;
|
||||
memcpy(&len,&dataSeg[8],4);
|
||||
cout<<"len: "<<len<<endl;
|
||||
memcpy(rawdata,&dataSeg[12],(datalen-HEAD_LEN));
|
||||
cout<<"rawdata: "<<rawdata<<endl;
|
||||
cout<<"***************************************"<<endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// brief : 往ndn_socket中写入数据
|
||||
// param : data 数据
|
||||
// len 数据长度
|
||||
// dname_base 数据包的前缀名称
|
||||
int Ndn_socket::write(const char * data , int len , string dname_base ) {
|
||||
// 给本机前缀加一个start_ts命名段
|
||||
if(dname_base[dname_base.length()-1] != '/') {
|
||||
dname_base += ("/"+this->start_ts+"/") ;
|
||||
}
|
||||
// 计算拆分成的数据段的数目
|
||||
int pkt_n = len/DATASEG_SZ;
|
||||
if(len%DATASEG_SZ != 0) {
|
||||
pkt_n ++ ;
|
||||
}
|
||||
// 给本机前缀加一个start_ts命名段、一个seq、一个"-seq+pkt_n"",
|
||||
// 用以附加在Block中传递给目的主机
|
||||
string pre_payload = dname_base + to_string(seq) + "-" + to_string(seq+pkt_n) ;
|
||||
// 记录该数据包的第一个数据段的seq
|
||||
unsigned int seq_first=seq;
|
||||
// 依次将分割出的每段数据放入face中
|
||||
for (int i = 0; i < pkt_n; i++) {
|
||||
Data data_pkt ;
|
||||
// 设置数据名字(“本机字段+start_ts+seq”)
|
||||
data_pkt.setName(dname_base + to_string(seq)) ;
|
||||
// cout<<"data_pkt_name: "<<dname_base + to_string(seq)<<endl;
|
||||
// c_len,当前数据段的长度
|
||||
int c_len = DATASEG_SZ ;
|
||||
if(len - i*DATASEG_SZ < DATASEG_SZ) {
|
||||
c_len = len - i*DATASEG_SZ ;
|
||||
}
|
||||
// 加段头
|
||||
// cout<<"c_len: "<<c_len<<endl;
|
||||
char resultData[c_len+HEAD_LEN];
|
||||
this->makeData(seq,seq_first,(unsigned int)len,data+i*DATASEG_SZ,c_len,resultData);
|
||||
char rawdata[c_len];
|
||||
// this->parseData(resultData,c_len+HEAD_LEN,rawdata);
|
||||
// 设置数据内容:这里需要修改数据格式,加一个头部
|
||||
data_pkt.setContent(reinterpret_cast<const uint8_t*>(resultData), c_len+HEAD_LEN) ;
|
||||
// data_pkt.setContent(reinterpret_cast<const uint8_t*>(data+i*DATASEG_SZ), c_len) ;
|
||||
//...
|
||||
this->m_keyChain.sign(data_pkt) ;
|
||||
//...
|
||||
this->m_face.put(data_pkt) ;
|
||||
// seq顺序递增
|
||||
seq ++ ;
|
||||
}
|
||||
// 给目的地前缀加一个start_ts命名段、一个seq,用以设置目的兴趣包的包名
|
||||
string pre_iname = daddr +"/"+ this->start_ts + "/" + to_string(seq) ;
|
||||
// 设置interest
|
||||
Interest pre_int(Name(pre_iname.data())) ;
|
||||
// cout<<"pre_interest name: "<<pre_iname<<endl;
|
||||
pre_int.setInterestLifetime(1_s) ;
|
||||
pre_int.setMustBeFresh(true) ;
|
||||
Block app_param = makeBinaryBlock(tlv::AppPrivateBlock1+1,
|
||||
pre_payload.data(), pre_payload.length());
|
||||
pre_int.setParameters(app_param) ;
|
||||
// 发送预请求兴趣包
|
||||
this->m_face.expressInterest(pre_int ,
|
||||
bind(&Ndn_socket::onData_pre,this,_1,_2),
|
||||
bind(&Ndn_socket::onNack_pre,this,_1,_2),
|
||||
bind(&Ndn_socket::onTimeout_pre,this,_1));
|
||||
//cout << "pre I>> : " << pre_int.getName() << endl;
|
||||
return len ;
|
||||
}
|
||||
|
||||
// 接收数据(从队列取出,放入data)
|
||||
int Ndn_socket::read(char *data , int buf_sz) {
|
||||
qp.r_queue.wait4data() ;
|
||||
if(this->state == false) {
|
||||
return -1 ;
|
||||
}
|
||||
//获取队列中的数据长度
|
||||
//(队列中数据较多,则按照read函数的参数取数据)
|
||||
int data_len = qp.r_queue.get_data_len() ;
|
||||
if(data_len > buf_sz) {
|
||||
data_len = buf_sz ;
|
||||
}
|
||||
// 拿到数据
|
||||
qp.r_queue.get_ndata(data , data_len) ;
|
||||
qp.r_queue.rmv_n(data_len) ;
|
||||
// 返回实际拿到的数据长度
|
||||
return data_len ;
|
||||
}
|
||||
|
||||
// 关闭face
|
||||
// 1. 不需要关闭线程m_tid吗?=> 直接关闭开ndn_socket的这个进程,也一样效果
|
||||
// 2. 为何要r_queue.push_ndata(&c_flag,1) ;???=> 让这个队列的waitdata()不阻塞
|
||||
// 用来给read()函数返回一个-1,而不是无限循环等待。
|
||||
int Ndn_socket::close(){
|
||||
if(this->state == false ) {
|
||||
return 0 ;
|
||||
}
|
||||
this->state = false ;
|
||||
|
||||
char c_flag = 'c' ;
|
||||
qp.r_queue.push_ndata(&c_flag,1) ;
|
||||
|
||||
// 等待兴趣包完全被处理,就关掉face
|
||||
while(m_face.getNPendingInterests() > 0){
|
||||
usleep(10000) ;
|
||||
}
|
||||
this->m_face.shutdown() ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
// 开启face
|
||||
void *Ndn_socket::run(void *param){
|
||||
Face *face_p = (Face*)param ;
|
||||
face_p->processEvents(time::milliseconds::zero(), true) ;
|
||||
}
|
||||
|
||||
// -----------------------NDN中的常见函数-----------------------
|
||||
|
||||
void Ndn_socket::onInterest(const InterestFilter& filter,
|
||||
const Interest& interest) {
|
||||
//cout << "onInterest : " << interest.getName() << endl ;
|
||||
if(interest.hasParameters()){
|
||||
|
||||
uint8_t p_type = 0 ;
|
||||
// 为何不是“memcpy(&p_type , interest.getParameters().type() , 1) ;”?
|
||||
// 不是要取Block的Type吗??这里可以进一步探究尝试。
|
||||
memcpy(&p_type , interest.getParameters().value() , 1) ;
|
||||
// memcpy(&p_type , interest.getParameters().type() , 1) ;
|
||||
|
||||
if(p_type == tlv::AppPrivateBlock1 + 1) { // 预请求包
|
||||
// 取Block
|
||||
Block dname_block(interest.getParameters().value() ,
|
||||
interest.getParameters().value_size()) ;
|
||||
// 取Block的数值
|
||||
string datas_name((char*)dname_block.value() ,
|
||||
dname_block.value_size()) ;
|
||||
// cout << "datas_name : " <<datas_name << endl ;
|
||||
// format : /ndn/edu/pkusz/node11/vpn/5-9
|
||||
|
||||
// 拿到seq以及seq+pkt_n
|
||||
int idx1 = datas_name.rfind('/')+1 ;
|
||||
int first, last ;
|
||||
sscanf(datas_name.data()+idx1 , "%d-%d" , &first , &last) ;
|
||||
string iname_base = datas_name.substr(0, idx1) ;
|
||||
|
||||
// 判断是否更换了新的ndn_sockt
|
||||
if(iname_base!=this->faddr){
|
||||
qp.initSelf();
|
||||
this->faddr=iname_base;
|
||||
}
|
||||
|
||||
// 依次请求该条信息的每个数据段
|
||||
//(数据产生者的前缀隐藏在Block中)
|
||||
for (int i = first; i < last; i++) {
|
||||
string interest_name = iname_base+ std::to_string(i) ;
|
||||
// cout<<"data interest name: "<<interest_name<<endl;
|
||||
Interest request_int(Name(interest_name.data())) ;
|
||||
request_int.setInterestLifetime(1_s) ;
|
||||
this->m_face.expressInterest(request_int ,
|
||||
bind(&Ndn_socket::onData,this,_1,_2),
|
||||
bind(&Ndn_socket::onNack,this,_1,_2),
|
||||
bind(&Ndn_socket::onTimeout,this,_1));
|
||||
//cout << "I>> : " << request_int.getName() << endl ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 发送兴趣包请求到的数据立即放入缓存队列
|
||||
void Ndn_socket::onData(const Interest& interest , const Data& data){
|
||||
int data_sz = data.getContent().value_size() ;
|
||||
// cout<<"data_sz: "<<data_sz<<endl;
|
||||
// r_queue.push_ndata(reinterpret_cast<const char*>(data.getContent().value()),
|
||||
// data_sz) ;
|
||||
qp.pushDataSegment(reinterpret_cast<const char*>(data.getContent().value()),
|
||||
data_sz);
|
||||
//cout << "D<< :" << data.getName() << " sz = " << data_sz << endl ;
|
||||
}
|
||||
|
||||
// 预请求兴趣包的onData
|
||||
void Ndn_socket::onData_pre(const Interest& interest , const Data& data){
|
||||
//cout << "pre D<< :" << data.getName() << " sz = " <<
|
||||
//data.getContent().value_size() << endl ;
|
||||
}
|
||||
|
||||
void Ndn_socket::onNack(const Interest& interest, const Nack& nack){
|
||||
cout << "Nack : "<< interest.getName() << endl ;
|
||||
long lifetime = interest.getInterestLifetime().count() ;
|
||||
if(lifetime > 3000) return ;
|
||||
if(this->state == false) return ;
|
||||
sleep(1) ;
|
||||
Interest interest_new(interest.getName());
|
||||
interest_new.setMustBeFresh(true) ;
|
||||
boost::chrono::milliseconds new_lifetime(lifetime+200) ;
|
||||
interest_new.setInterestLifetime(new_lifetime);
|
||||
this->m_face.expressInterest(interest_new,
|
||||
bind(&Ndn_socket::onData,this,_1,_2),
|
||||
bind(&Ndn_socket::onNack,this,_1,_2),
|
||||
bind(&Ndn_socket::onTimeout,this,_1));
|
||||
cout << "I>> : " << interest_new.getName() << endl ;
|
||||
//this->m_face.shutdown() ;
|
||||
}
|
||||
|
||||
// 预请求兴趣包的onNack
|
||||
void Ndn_socket::onNack_pre(const Interest& interest, const Nack& nack){
|
||||
cout << "pre Nack : "<< interest.getName() << endl ;
|
||||
cout << "listen : " << this->maddr << endl ;
|
||||
long lifetime = interest.getInterestLifetime().count() ;
|
||||
if(lifetime > 3000 || this->state == false ) return ;
|
||||
sleep(1) ;
|
||||
Interest interest_new(interest.getName());
|
||||
interest_new.setMustBeFresh(true) ;
|
||||
boost::chrono::milliseconds new_lifetime(lifetime+200) ;
|
||||
interest_new.setInterestLifetime(new_lifetime);
|
||||
interest_new.setParameters(interest.getParameters());
|
||||
this->m_face.expressInterest(interest_new,
|
||||
bind(&Ndn_socket::onData_pre,this,_1,_2),
|
||||
bind(&Ndn_socket::onNack_pre,this,_1,_2),
|
||||
bind(&Ndn_socket::onTimeout_pre,this,_1));
|
||||
cout << "pre I>> : " << interest_new.getName() << endl ;
|
||||
}
|
||||
|
||||
void Ndn_socket::onTimeout(const Interest& interest) {
|
||||
cout << "Time out " << interest.getName() << endl ;
|
||||
long lifetime = interest.getInterestLifetime().count() ;
|
||||
if(lifetime > 3000) return ;
|
||||
if(this->state == false) return ;
|
||||
Interest interest_new(interest.getName());
|
||||
boost::chrono::milliseconds new_lifetime(lifetime+200) ;
|
||||
interest_new.setInterestLifetime(new_lifetime);
|
||||
this->m_face.expressInterest(interest_new,
|
||||
bind(&Ndn_socket::onData,this,_1,_2),
|
||||
bind(&Ndn_socket::onNack,this,_1,_2),
|
||||
bind(&Ndn_socket::onTimeout,this,_1));
|
||||
}
|
||||
|
||||
// 预请求兴趣包的onTimeout
|
||||
void Ndn_socket::onTimeout_pre(const Interest& interest) {
|
||||
}
|
||||
|
||||
// face注册时,注册失败的提示信息
|
||||
void Ndn_socket::onRegisterFailed(const Name& prefix, const std::string& reason)
|
||||
{
|
||||
std::cerr << "ERROR: Failed to register prefix \""
|
||||
<< prefix << "\" in local hub's daemon (" << reason << ")"
|
||||
<< std::endl;
|
||||
m_face.shutdown();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
#ifndef _NDN_SOCKET_H_
|
||||
#define _NDN_SOCKET_H_
|
||||
// 功能 : 启动一个face,并往固定的前缀发送数据
|
||||
#include <iostream>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <errno.h>
|
||||
#include <exception>
|
||||
#include "PriorQueuePool/QueuePool.h"
|
||||
#include <sys/time.h>
|
||||
#define HEAD_LEN 12 //数据段头部长度
|
||||
#define DATASEG_SZ 8000 //最大数据段长度
|
||||
|
||||
using std::string ;
|
||||
using ndn::Face ;
|
||||
using ndn::KeyChain ;
|
||||
using ndn::Interest ;
|
||||
using ndn::InterestFilter ;
|
||||
using ndn::Data ;
|
||||
using ndn::Name ;
|
||||
using ndn::lp::Nack ;
|
||||
|
||||
class Ndn_socket
|
||||
{
|
||||
public:
|
||||
Ndn_socket();
|
||||
~Ndn_socket();
|
||||
|
||||
int listen(const char * prefix) ; // 监听一个前缀
|
||||
int set_daddr(const char * prefix) ; // 设置一个目标地址
|
||||
string get_daddr() ;
|
||||
|
||||
// 发送数据
|
||||
int write(const string & data) ;
|
||||
int write(const char * data , int len) ;
|
||||
int write(const char * data , int len , string dname_base) ;
|
||||
int write(const uint8_t * data , int len) ;
|
||||
int write(const uint8_t * data , int len , string dname_base) ;
|
||||
// 接收数据
|
||||
int read(char *data , int buf_sz) ;
|
||||
//int read(char *data ) ;
|
||||
|
||||
int close() ; // 关闭线程-processEvent
|
||||
|
||||
private:
|
||||
void onInterest(const InterestFilter& filter, const Interest& interest) ;
|
||||
|
||||
void onData(const Interest& interest , const Data& data);
|
||||
void onData_pre(const Interest& interest , const Data& data);
|
||||
|
||||
void onNack(const Interest& interest, const Nack& nack);
|
||||
void onNack_pre(const Interest& interest, const Nack& nack);
|
||||
|
||||
void onTimeout(const Interest& interest) ;
|
||||
void onTimeout_pre(const Interest& interest) ;
|
||||
|
||||
void onRegisterFailed(const Name& prefix, const std::string& reason) ;
|
||||
|
||||
static void *run(void *param) ;
|
||||
|
||||
// 给数据段加段头
|
||||
int makeData(unsigned int seq,unsigned int seq_first,
|
||||
unsigned int len,const char *data,int datalen,char *resultData);
|
||||
// 解析数据段=>用于测试
|
||||
int parseData(char* dataSeg,int datalen,char* rawdata);
|
||||
|
||||
private:
|
||||
/* data */
|
||||
pthread_t m_tid ;
|
||||
|
||||
string maddr ; // 本机的地址
|
||||
string daddr ; // 推送数据到的目的地址
|
||||
string faddr ; //当前接收的数据段的源地址
|
||||
|
||||
unsigned int seq ;//切割后数据段的序列号
|
||||
QueuePool qp; //二级队列缓存数据
|
||||
string start_ts ; //时间戳
|
||||
bool state ; //m_face是否注册成功的标志
|
||||
|
||||
Face m_face ; //数据收发接口
|
||||
KeyChain m_keyChain ; //
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
#ifndef _NDNP2P_RECV_H_
|
||||
#define _NDNP2P_RECV_H_
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
#include <iostream>
|
||||
#include "ndn_socket.h"
|
||||
#define BUFF_SZ 500
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
Ndn_socket ndn_socket;
|
||||
ndn_socket.listen("/localhost/nfd/recv1") ;
|
||||
|
||||
char buff[BUFF_SZ];
|
||||
int read_n = 0 ; //收到的数据总长度
|
||||
int recv_count = 0 ;
|
||||
|
||||
while((read_n = ndn_socket.read(buff,BUFF_SZ)) > 0){
|
||||
cout << "count = " << ++recv_count << endl ;
|
||||
cout<<"recv buff: ";
|
||||
for(int x=0;x<BUFF_SZ;x++){
|
||||
cout<<buff[x];
|
||||
}
|
||||
cout<<endl;
|
||||
cout << "recv len = " << read_n << endl ;
|
||||
cout<<endl;
|
||||
// cout<<endl<<endl<<endl<<endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#include <iostream>
|
||||
#include "ndn_socket.h"
|
||||
#define BUFF_SZ 500
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
Ndn_socket ndn_socket;
|
||||
ndn_socket.listen("/localhost/nfd/recv2") ;
|
||||
|
||||
char buff[BUFF_SZ];
|
||||
int read_n = 0 ; //收到的数据总长度
|
||||
int recv_count = 0 ;
|
||||
|
||||
while((read_n = ndn_socket.read(buff,BUFF_SZ)) > 0){
|
||||
cout << "count = " << ++recv_count << endl ;
|
||||
cout<<"recv buff: ";
|
||||
for(int x=0;x<BUFF_SZ;x++){
|
||||
cout<<buff[x];
|
||||
}
|
||||
cout<<endl;
|
||||
cout << "recv len = " << read_n << endl ;
|
||||
cout<<endl;
|
||||
// cout<<endl<<endl<<endl<<endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <iostream>
|
||||
#include "ndn_socket.h"
|
||||
#define BUFF_SZ 500
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
Ndn_socket ndn_socket ;
|
||||
ndn_socket.listen("/localhost/nfd/send") ;
|
||||
char buff[BUFF_SZ] ;
|
||||
|
||||
ndn_socket.set_daddr("/localhost/nfd/recv1") ;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
memset(buff, 'a'+i , BUFF_SZ) ;
|
||||
ndn_socket.write(buff , BUFF_SZ) ;
|
||||
cout<<"send buff: ";
|
||||
for(int x=0;x<BUFF_SZ;x++){
|
||||
cout<<buff[x];
|
||||
}
|
||||
cout<<endl;
|
||||
cout<<endl;
|
||||
}
|
||||
|
||||
ndn_socket.set_daddr("/localhost/nfd/recv2") ;
|
||||
for (int i = 5; i < 10; i++) {
|
||||
memset(buff, 'a'+i , BUFF_SZ) ;
|
||||
ndn_socket.write(buff , BUFF_SZ) ;
|
||||
cout<<"send buff: ";
|
||||
for(int x=0;x<BUFF_SZ;x++){
|
||||
cout<<buff[x];
|
||||
}
|
||||
cout<<endl;
|
||||
cout<<endl;
|
||||
}
|
||||
|
||||
ndn_socket.close() ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef _NDNP2P_SEND_H_
|
||||
#define _NDNP2P_SEND_H_
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,175 @@
|
||||
// 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;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#ifndef SOCKS_H_INCLUDED
|
||||
#define SOCKS_H_INCLUDED
|
||||
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "ccn_p2p/ndn_socket.h"
|
||||
|
||||
#define SERV_TCP_PORT 8888 /* Local listening port number */
|
||||
#define MAX_SIZE 1024*7120
|
||||
|
||||
// the address of socks server
|
||||
#define SOCKS5_SERVER_IP "127.0.0.1"
|
||||
#define SOCKS5_SERVER_PORT 9011
|
||||
|
||||
using namespace std;
|
||||
using std::pair;
|
||||
|
||||
class Client{
|
||||
private:
|
||||
// sockfd
|
||||
int sockfd;
|
||||
// sockaddr
|
||||
struct sockaddr_in serv_addr;
|
||||
/* Local listening port number */
|
||||
int port;
|
||||
|
||||
Ndn_socket mndn_socket ;
|
||||
// 本地兴趣包监听前缀
|
||||
string listen_prefix ;
|
||||
string base_listen_prefix;
|
||||
// 自增量
|
||||
unsigned int p_port_seq ;
|
||||
// 服务器兴趣包监听前缀
|
||||
string server_prefix ;
|
||||
string base_server_prefix;
|
||||
|
||||
public:
|
||||
// construction function
|
||||
Client(const string &s_prefix , const string &m_prefix){
|
||||
this->port=SERV_TCP_PORT;
|
||||
this->server_prefix = s_prefix;
|
||||
this->listen_prefix = m_prefix ;
|
||||
this->p_port_seq=0;
|
||||
this->base_listen_prefix=m_prefix+"_base";
|
||||
this->base_server_prefix=s_prefix+"_base";
|
||||
mndn_socket.set_daddr(base_server_prefix.data()) ;
|
||||
cout << "base_server_prefix: "<<base_server_prefix << endl ;
|
||||
}
|
||||
Client(int port , const string &s_prefix , const string &m_prefix){
|
||||
this->port=port;
|
||||
this->server_prefix = s_prefix ;
|
||||
this->listen_prefix = m_prefix ;
|
||||
this->p_port_seq=0;
|
||||
this->base_listen_prefix=m_prefix+"_base";
|
||||
this->base_server_prefix=s_prefix+"_base";
|
||||
mndn_socket.set_daddr(base_server_prefix.data()) ;
|
||||
cout << "base_server_prefix: "<<base_server_prefix << endl ;
|
||||
}
|
||||
~Client(){
|
||||
}
|
||||
|
||||
// listen to the local port
|
||||
void listenLocal() ;
|
||||
void ndn_listen_local(string prefix) ;
|
||||
// waiting for the local port's connection
|
||||
int acceptLocal();
|
||||
// connect to the socks5-server
|
||||
void ndn_connSockes5Server(Ndn_socket &ndn_socket , string new_prefix);
|
||||
// data transmission shake
|
||||
void ndn_transData(Ndn_socket &ndn_socket , int newsockfd );
|
||||
// forever listenner function
|
||||
void ndn_forever();
|
||||
// server start
|
||||
void start();
|
||||
|
||||
private :
|
||||
static void *ndn_thread1(void *val);
|
||||
static void *ndn_thread2(void *val);
|
||||
string get_newprefix() ;
|
||||
};
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,44 @@
|
||||
#include "Client.h"
|
||||
using namespace std;
|
||||
|
||||
// 输出提示信息
|
||||
void alert_usage(){
|
||||
cout << "Usage : ./client -s /aaa/nfd/vpn/server -c /aaa/nfd/vpn/client" << endl ;
|
||||
exit(0) ;
|
||||
}
|
||||
|
||||
// 解析参数
|
||||
void parse_arg(string &server_prefix , string &m_prefix , int argc , char **argv){
|
||||
if(argc < 5){
|
||||
alert_usage() ;
|
||||
}
|
||||
string cmd1 = argv[1] ;
|
||||
string cmd2 = argv[3] ;
|
||||
if(cmd1 == "-s"){
|
||||
server_prefix = argv[2] ;
|
||||
}else if(cmd1 == "-c"){
|
||||
m_prefix = argv[2] ;
|
||||
}else{
|
||||
alert_usage() ;
|
||||
}
|
||||
if(cmd2 == "-s"){
|
||||
server_prefix = argv[4] ;
|
||||
}else if(cmd2 == "-c"){
|
||||
m_prefix = argv[4] ;
|
||||
}else{
|
||||
alert_usage() ;
|
||||
}
|
||||
if(server_prefix == "" || m_prefix == "") alert_usage() ;
|
||||
}
|
||||
|
||||
// 主函数入口
|
||||
int main(int argc , char **argv){
|
||||
string server_prefix = "/aaa/nfd/vpn/server" ;
|
||||
string client_prefix = "/aaa/nfd/vpn/client" ;
|
||||
|
||||
parse_arg(server_prefix , client_prefix, argc, argv) ;
|
||||
|
||||
Client *client=new Client(server_prefix,client_prefix);
|
||||
client->start();
|
||||
delete client;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,47 @@
|
||||
INC_DIR= -I. -I..
|
||||
SRC_DIR = ./deamon ./face ./common ./table
|
||||
OBJ_DIR = ./objs
|
||||
|
||||
#SRC=$(wildcard $(SRC_DIR)/*.cpp)
|
||||
|
||||
SRC= ClientMain.cpp \
|
||||
Client.cpp \
|
||||
../ccn_p2p/PriorQueuePool/r_queue.cpp \
|
||||
../ccn_p2p/PriorQueuePool/PriorQueue.cpp \
|
||||
../ccn_p2p/PriorQueuePool/QueuePool.cpp \
|
||||
../ccn_p2p/ndn_socket.cpp
|
||||
|
||||
|
||||
OBJS := $(patsubst %.cpp, %.o,$(SRC))
|
||||
|
||||
CC := g++
|
||||
CFLAGS := -g -std=c++14 ${INC_DIR}
|
||||
LFLAGS := -lpthread -lpcap -lndn-cxx -lboost_system -ljsoncpp
|
||||
TARGET := client
|
||||
|
||||
all: ${TARGET}
|
||||
|
||||
# 下面这个是什么作用?
|
||||
endndc : ./endndc/endndc.cpp
|
||||
g++ ./endndc/endndc.cpp -o ./endndc/endndc
|
||||
|
||||
$(TARGET): ${OBJS}
|
||||
$(CC) ${OBJS} -o ${TARGET} $(LFLAGS)
|
||||
|
||||
${OBJS} : %.o: %.cpp %.h
|
||||
${CC} ${CFLAGS} -c $< -o $@
|
||||
@#echo $^
|
||||
|
||||
|
||||
#$@ 表示目标文件
|
||||
#$^ 表示所有依赖文件
|
||||
#$< 表示第一个依赖文件
|
||||
#$? 表示比目标新的依赖文件列表
|
||||
|
||||
clean:
|
||||
rm -rf $(TARGET) *.o ${OBJS}
|
||||
|
||||
test:
|
||||
echo $(SRC)
|
||||
echo $(OBJS)
|
||||
echo $(CFLAGS)
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "Socks5Server.h"
|
||||
using namespace std;
|
||||
|
||||
// 输出提示信息
|
||||
void alert_usage(){
|
||||
cout << "Usage : ./server -s /aaa/nfd/vpn/server " << endl ;
|
||||
exit(0) ;
|
||||
}
|
||||
|
||||
// 解析参数
|
||||
void parse_arg(string &server_prefix , int argc , char **argv){
|
||||
if(argc < 3){
|
||||
alert_usage() ;
|
||||
}
|
||||
string cmd1 = argv[1] ;
|
||||
if(cmd1 == "-s"){
|
||||
server_prefix = argv[2] ;
|
||||
}else{
|
||||
alert_usage() ;
|
||||
}
|
||||
if(server_prefix == "" ) alert_usage() ;
|
||||
}
|
||||
|
||||
// 主函数入口
|
||||
int main(int argc , char **argv){
|
||||
string server_prefix ;
|
||||
parse_arg(server_prefix , argc , argv) ;
|
||||
Socks5Server *ss_server=new Socks5Server(server_prefix);
|
||||
ss_server->start();
|
||||
delete ss_server;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,372 @@
|
||||
// simulate socks5-server. coding by wefree in 2019.12
|
||||
#include "Socks5Server.h"
|
||||
using namespace std;
|
||||
|
||||
// listen to the local port
|
||||
void Socks5Server::ndn_listen_local(string prefix){
|
||||
mndn_socket.listen(prefix.data()) ;
|
||||
cout << "listen on : " << prefix << endl ;
|
||||
}
|
||||
|
||||
// waiting for the local port's connection
|
||||
string Socks5Server::ndn_accept_local(string new_prefix) {
|
||||
char buff[1000] ;
|
||||
memset(buff,0,1000) ;
|
||||
cout<<"Waitting connection [socks5-server] ..."<<endl;
|
||||
int read_n = mndn_socket.read(buff,1000) ;
|
||||
cout<<"Acceptted a connection [socks5-server]"<<endl;
|
||||
|
||||
string client_prefix = buff ;
|
||||
cout << "client_prefix : " << client_prefix << endl ;
|
||||
|
||||
return client_prefix ;
|
||||
}
|
||||
|
||||
// a handshake for the sub-negotiation method
|
||||
int Socks5Server::ndn_negotShake(Ndn_socket &ndn_socket){
|
||||
int flag=0;
|
||||
//Get 2 bytes of information from the client
|
||||
// - socks version number, total number of negotiation methods
|
||||
char buf1[1];
|
||||
char buf2[2];
|
||||
cout << "ndn_negotShake before read" << endl ;
|
||||
// 测试代码段BEGIN
|
||||
// char buf8[8];
|
||||
// char buf10[10];
|
||||
// char buf20[20];
|
||||
// if (ndn_socket.read(buf20 , 20) < 0) {
|
||||
// cout<<"cannot test the metaphysics bug"<<endl;
|
||||
// flag=1;
|
||||
// return flag;
|
||||
// }else{
|
||||
// for(int i=0;i<20;i++){ // to test it.
|
||||
// printf("%x--%c ", buf20[i],buf20[i]);
|
||||
// }
|
||||
// flag=1;
|
||||
// return flag;
|
||||
// }
|
||||
// 测试代码段END
|
||||
if (ndn_socket.read(buf2 , 2) < 0) {
|
||||
cout<<"cannot get version-nmethod"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
if ((uint8_t)buf2[0] != this->socks_vision) {
|
||||
cout<<"socks version is wrong"<<endl;
|
||||
cout<<"version-nmethod: ";
|
||||
printf("%x--%c ", buf2[0],buf2[0]);
|
||||
printf("%x--%c \n", buf2[1],buf2[1]);
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
if ((uint8_t)buf2[1] <= 0) {
|
||||
cout<<"nmethod is wrong"<<endl;
|
||||
cout<<"version-nmethod: ";
|
||||
printf("%x--%c ", buf2[0],buf2[0]);
|
||||
printf("%x--%c \n", buf2[1],buf2[1]);
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
cout<<"version-nmethod: ";
|
||||
printf("%x ", buf2[0]);
|
||||
printf("%x \n", buf2[1]);
|
||||
|
||||
//negotiation methods
|
||||
int nmethods = (uint8_t)buf2[1];
|
||||
// the method contains 0 when the m_flag==1
|
||||
int m_flag = 0;
|
||||
for (int i = 0; i < nmethods; i++) {
|
||||
ndn_socket.read(buf1,1) ;
|
||||
if ((uint8_t)(buf1[0]) == 0) {
|
||||
m_flag = 1;
|
||||
}
|
||||
cout<<"nmethods: ";
|
||||
printf("%x\n", buf1[0]);
|
||||
}
|
||||
if (m_flag == 0) {
|
||||
cout<<"methods donot have 0"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
//Return request reply (no sub-negotiation required)
|
||||
uint8_t msg2[2];
|
||||
msg2[0] = this->socks_vision;
|
||||
msg2[1] = this->ui0;
|
||||
if (ndn_socket.write(msg2,2) < 0) {
|
||||
cout<<"cannot send socks-methond-reply"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
// a handshake for the connection information
|
||||
// to remote server
|
||||
pair<int,int> Socks5Server::ndn_connShake(Ndn_socket &ndn_socket){
|
||||
// right flag, the loop is going on when th flag==0
|
||||
int flag=0;
|
||||
char buf4[4];
|
||||
if (ndn_socket.read(buf4,4) < 0 ) {
|
||||
cout<<"cannot get version-cmd-_-addressType"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
cout<<"version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
if ((uint8_t)buf4[0] != 5) {
|
||||
cout<<"version is wrong. version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
uint8_t cmd = (uint8_t)buf4[1];
|
||||
if(cmd!=1){
|
||||
cout<<"cmd is not 1"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
uint8_t addressType = (uint8_t)buf4[3];
|
||||
if(addressType!=1){
|
||||
cout<<"address is not ipv4"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
|
||||
//Get the IP address of the destination server of URL request from the client
|
||||
char* r_address;
|
||||
char* domin_address;
|
||||
int remote_addr_length=4;
|
||||
if (addressType == 1) {//ipv4
|
||||
remote_addr_length=4;
|
||||
r_address=new char[4];
|
||||
if (ndn_socket.read(r_address,4) < 0) {
|
||||
cout<<"cannot get the ipv4\n"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
printf("ipv4: %d %d",(uint8_t)r_address[0],(uint8_t)r_address[1]);
|
||||
printf(" %d %d\n",(uint8_t)r_address[2],(uint8_t)r_address[3]);
|
||||
}else{
|
||||
cout<<"address is not ipv4"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
|
||||
//Listener port of destination server for URL request from client
|
||||
char r_port[2];
|
||||
//if (recv(newsockfd, r_port, 2, 0) == -1) {
|
||||
if (ndn_socket.read(r_port,2) < 0) {
|
||||
cout<<"cannot get the port\n"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
printf("port: %d %d\n", (uint8_t)r_port[0],(uint8_t)r_port[1]);
|
||||
|
||||
//When the connection to the remote server is successful,
|
||||
// remote server
|
||||
int remote_sockfd;
|
||||
try
|
||||
{
|
||||
if (cmd == 1) {
|
||||
if (addressType == 1){//ipv4
|
||||
//Connect to remote destination server
|
||||
struct sockaddr_in remote_addr;
|
||||
remote_sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
bzero((char *)&remote_addr, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
memcpy(&(remote_addr.sin_addr.s_addr),r_address,remote_addr_length);
|
||||
memcpy(&(remote_addr.sin_port),r_port,2);
|
||||
cout<<"connecting to ipv4..."<<endl;
|
||||
int res_c=connect(remote_sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
if(res_c==-1){
|
||||
cout<<"connect error"<<endl;
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}else{
|
||||
cout<<"connected ipv4"<<endl;
|
||||
printf("Connected to %s:%d\n",inet_ntoa(remote_addr.sin_addr),remote_addr.sin_port);
|
||||
}
|
||||
}else{
|
||||
//...
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
printf("cmd is not connection\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
|
||||
//Return connection information to client
|
||||
uint8_t *connRrt;
|
||||
if(addressType==1){//ipv4
|
||||
//getsocketname()
|
||||
sockaddr_in cs_addr;
|
||||
memset(&cs_addr,0,sizeof(cs_addr));
|
||||
int cs_len=sizeof(cs_addr);
|
||||
int res_sn=getsockname(remote_sockfd,(struct sockaddr *)&cs_addr,(socklen_t *)&cs_len);
|
||||
cout<<"Current connection:"<<inet_ntoa(cs_addr.sin_addr)<<":"<<ntohs(cs_addr.sin_port)<<endl;
|
||||
// return info
|
||||
connRrt=new uint8_t[10];
|
||||
connRrt[0]=socks_vision;
|
||||
connRrt[1]=ui0;
|
||||
connRrt[2]=ui0;
|
||||
connRrt[3]=addressType;
|
||||
memcpy(&connRrt[4],&(cs_addr.sin_addr.s_addr),remote_addr_length);
|
||||
memcpy(&connRrt[8],&(cs_addr.sin_port),2);
|
||||
cout<<"the reply ip:"<<endl;
|
||||
for(int i=0;i<4;i++){
|
||||
printf("%d ",(uint8_t)connRrt[4+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
cout<<"the reply port:"<<endl;
|
||||
for(int i=0;i<2;i++){
|
||||
printf("%d ",(uint8_t)connRrt[8+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
if (ndn_socket.write(connRrt,10) < 0) {
|
||||
printf("cannot send url-reply\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
}else{}
|
||||
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
uint8_t err[6];
|
||||
err[0] = socks_vision;
|
||||
err[1] = ui5;
|
||||
err[2] = ui0;
|
||||
err[3] = addressType;
|
||||
err[4] = ui0;
|
||||
err[5] = ui0;
|
||||
if (ndn_socket.write(err,6) < 0) {
|
||||
printf("cannot send url-err-reply\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
}
|
||||
return make_pair(remote_sockfd,flag);
|
||||
};
|
||||
|
||||
// data transmission shake
|
||||
void Socks5Server::ndn_transData(string new_prefix , string client_prefix){
|
||||
pid_t fpid1;
|
||||
while ( ( fpid1 = fork() ) < 0 ){
|
||||
cout << "create child process failled. Retry..." << endl;
|
||||
}
|
||||
if ( 0 == fpid1 ) {
|
||||
cout<<"child process beginning: "<<endl;
|
||||
Ndn_socket ndn_socket ;
|
||||
ndn_socket.listen(new_prefix.data()) ;
|
||||
ndn_socket.set_daddr(client_prefix.data()) ;
|
||||
cout << "new server ndnsocket's daddr :" << ndn_socket.get_daddr() << endl ;
|
||||
|
||||
// 将服务器端与客户端进程对接的ndn_socket的兴趣前缀发送给client
|
||||
cout<<"new_prefix: "<<new_prefix<<endl;
|
||||
ndn_socket.write(new_prefix) ;
|
||||
|
||||
if(this->ndn_negotShake(ndn_socket)>0){
|
||||
cout<<"negotShake error"<<endl;
|
||||
ndn_socket.close() ;
|
||||
exit(0) ;
|
||||
}
|
||||
pair<int,int> pairval= ndn_connShake(ndn_socket) ;
|
||||
if(pairval.second>0){
|
||||
cout<<"connShake error"<<endl;
|
||||
if(pairval.first>0){
|
||||
close(pairval.first);
|
||||
}
|
||||
ndn_socket.close() ;
|
||||
exit(0);
|
||||
}
|
||||
int remote_sockfd = pairval.first;
|
||||
|
||||
printf("Data transmission is beginning.\n");
|
||||
void *sockfds[2] = {&ndn_socket,&remote_sockfd} ;
|
||||
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);
|
||||
// exit the son process
|
||||
exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
// forever listenner function
|
||||
void Socks5Server::ndn_forever(){
|
||||
while(true){
|
||||
string new_prefix = this->listen_prefix+ to_string(p_port_seq++) ;
|
||||
string client_prefix = this->ndn_accept_local(new_prefix) ;
|
||||
|
||||
ndn_transData(new_prefix, client_prefix ) ;
|
||||
}
|
||||
};
|
||||
|
||||
// server start
|
||||
void Socks5Server::start(){
|
||||
this->ndn_listen_local(base_listen_prefix) ;
|
||||
this->ndn_forever() ;
|
||||
mndn_socket.close() ;
|
||||
};
|
||||
|
||||
// transfer data from local server host to remote-server
|
||||
void *Socks5Server::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 = 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 remote_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
cout << ">>>>>>>>>>>>>>>>>>>>thread1 end" << endl ;
|
||||
delete data;
|
||||
ndn_socketp->close() ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// transfer data form remote-server to local server host
|
||||
void *Socks5Server::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=recv(remote_sockfd, data, MAX_SIZE, 0);
|
||||
cout << "************recv from remote_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 << ">>>>>>>>>>>>>>>>>>>>thread2 end" << endl ;
|
||||
delete data;
|
||||
ndn_socketp->close() ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
#ifndef SOCKS_H_INCLUDED
|
||||
#define SOCKS_H_INCLUDED
|
||||
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "ccn_p2p/ndn_socket.h"
|
||||
|
||||
#define SERV_TCP_PORT 9011 /* Local listening port number */
|
||||
#define MAX_SIZE 1024*7120
|
||||
#define SOCKS5_VERSION 5
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Socks5Server{
|
||||
private:
|
||||
// sockfd
|
||||
int sockfd;
|
||||
// sockaddr
|
||||
struct sockaddr_in serv_addr;
|
||||
/* Local listening port number */
|
||||
int port;
|
||||
// socks version
|
||||
uint8_t socks_vision;
|
||||
// 2 commom numbers
|
||||
uint8_t ui0;
|
||||
uint8_t ui5;
|
||||
|
||||
Ndn_socket mndn_socket ;
|
||||
string listen_prefix ;
|
||||
string base_listen_prefix;
|
||||
unsigned int p_port_seq ;
|
||||
|
||||
public:
|
||||
// construction function
|
||||
Socks5Server(const string &server_prefix){
|
||||
this->port=SERV_TCP_PORT;
|
||||
this->ui0=0;
|
||||
this->ui5=5;
|
||||
this->socks_vision=SOCKS5_VERSION;
|
||||
this->p_port_seq = 0 ;
|
||||
this->listen_prefix = server_prefix ;
|
||||
this->base_listen_prefix=server_prefix+"_base";
|
||||
}
|
||||
Socks5Server(int port , const string &server_prefix){
|
||||
this->port=port;
|
||||
this->ui0=0;
|
||||
this->ui5=5;
|
||||
this->socks_vision=SOCKS5_VERSION;
|
||||
this->p_port_seq = 0 ;
|
||||
this->listen_prefix = server_prefix ;
|
||||
this->base_listen_prefix=server_prefix+"_base";
|
||||
}
|
||||
~Socks5Server(){
|
||||
}
|
||||
|
||||
// listen to the local port
|
||||
void ndn_listen_local(string prefix) ;
|
||||
|
||||
// waiting for the local port's connection
|
||||
string ndn_accept_local(string new_prefix) ;
|
||||
// a handshake for the sub-negotiation method
|
||||
int ndn_negotShake(Ndn_socket &ndn_socket);
|
||||
// a handshake for the connection information
|
||||
// to remote server
|
||||
pair<int,int> ndn_connShake(Ndn_socket &ndn_socket);
|
||||
// data transmission shake
|
||||
void ndn_transData(string new_prefix , string client_prefix);
|
||||
|
||||
// forever listenner function
|
||||
void ndn_forever();
|
||||
// server start
|
||||
void start();
|
||||
|
||||
// ndn 监听线程:数据传输
|
||||
static void *ndn_thread1(void *val);
|
||||
static void *ndn_thread2(void *val);
|
||||
};
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,46 @@
|
||||
INC_DIR= -I. -I..
|
||||
SRC_DIR = ./deamon ./face ./common ./table
|
||||
OBJ_DIR = ./objs
|
||||
|
||||
#SRC=$(wildcard $(SRC_DIR)/*.cpp)
|
||||
|
||||
SRC= ServerMain.cpp \
|
||||
Socks5Server.cpp \
|
||||
../ccn_p2p/PriorQueuePool/r_queue.cpp \
|
||||
../ccn_p2p/PriorQueuePool/PriorQueue.cpp \
|
||||
../ccn_p2p/PriorQueuePool/QueuePool.cpp \
|
||||
../ccn_p2p/ndn_socket.cpp
|
||||
|
||||
|
||||
OBJS := $(patsubst %.cpp, %.o,$(SRC))
|
||||
|
||||
CC := g++
|
||||
CFLAGS := -g -std=c++14 ${INC_DIR}
|
||||
LFLAGS := -lpthread -lpcap -lndn-cxx -lboost_system -ljsoncpp
|
||||
TARGET := server
|
||||
|
||||
all: ${TARGET}
|
||||
|
||||
endndc : ./endndc/endndc.cpp
|
||||
g++ ./endndc/endndc.cpp -o ./endndc/endndc
|
||||
|
||||
$(TARGET): ${OBJS}
|
||||
$(CC) ${OBJS} -o ${TARGET} $(LFLAGS)
|
||||
|
||||
${OBJS} : %.o: %.cpp %.h
|
||||
${CC} ${CFLAGS} -c $< -o $@
|
||||
@#echo $^
|
||||
|
||||
|
||||
#$@ 表示目标文件
|
||||
#$^ 表示所有依赖文件
|
||||
#$< 表示第一个依赖文件
|
||||
#$? 表示比目标新的依赖文件列表
|
||||
|
||||
clean:
|
||||
rm -rf $(TARGET) *.o ${OBJS}
|
||||
|
||||
test:
|
||||
echo $(SRC)
|
||||
echo $(OBJS)
|
||||
echo $(CFLAGS)
|
||||
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"CurrentProjectSetting": "无配置"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"ExpandedNodes": [
|
||||
""
|
||||
],
|
||||
"SelectedNode": "\\server.cpp",
|
||||
"PreviewInSolutionExplorer": false
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,337 @@
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#define SERV_TCP_PORT 9011 /* Local listening port number */
|
||||
#define MAX_SIZE 1024*100
|
||||
|
||||
using namespace std;
|
||||
|
||||
int sockfd, newsockfd;
|
||||
|
||||
// simulate socks5-server
|
||||
// usage:
|
||||
// 1. "g++ -o server server.cpp -lpthread"
|
||||
// 2. "./server"
|
||||
// curl -v --socks5 127.0.0.1:9011 https://www.baidu.com => ok
|
||||
// firefox browser => ok
|
||||
|
||||
void * thread_fun1(void * val){
|
||||
int local_sockfd=newsockfd;
|
||||
int remote_sockfd = *((int*)val);
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(local_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from local_sock datalen = " << datalen << endl ;
|
||||
if (datalen<= 0) {
|
||||
break ;
|
||||
}else{ // send to remote server
|
||||
send_len = send(remote_sockfd, data, datalen, 0) ;
|
||||
cout << "send to remote_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void * thread_fun2(void * val){
|
||||
int local_sockfd = newsockfd;
|
||||
int remote_sockfd = *((int*)val);
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(remote_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from remote_sock datalen = " << datalen << endl ;
|
||||
if (datalen <= 0) {
|
||||
//nothing
|
||||
break;
|
||||
}else{
|
||||
// send to localhost
|
||||
send_len = send(local_sockfd, data, datalen, 0) ;
|
||||
cout << "send to local_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
socklen_t clilen;
|
||||
struct sockaddr_in cli_addr, serv_addr;
|
||||
int port;
|
||||
char string[MAX_SIZE];
|
||||
int len;
|
||||
|
||||
port = SERV_TCP_PORT;
|
||||
|
||||
uint8_t socks_vision = 5;
|
||||
int remote_sockfd;
|
||||
struct sockaddr_in remote_addr;
|
||||
int remote_addr_length=6;//the length of remote server address
|
||||
uint8_t ui0 = 0;
|
||||
uint8_t ui5 = 5;
|
||||
|
||||
//////////////////////////////Listen to local port number 9011-Begin//////////////////////
|
||||
/* open a TCP socket (an Internet stream socket) */
|
||||
(sockfd = socket(AF_INET, SOCK_STREAM, 0));
|
||||
|
||||
/* bind the local address, so that the cliend can send to server */
|
||||
bzero((char *)&serv_addr, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
serv_addr.sin_port = htons(port);
|
||||
|
||||
// bind
|
||||
// bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
|
||||
while( bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
|
||||
sleep(1) ;
|
||||
cout << "bind fail" << endl ;
|
||||
// bind failled.
|
||||
};
|
||||
|
||||
listen(sockfd, 10);
|
||||
|
||||
//////////////////////////////Listen to local port number 9011-End//////////////////////
|
||||
|
||||
while (true) {
|
||||
//////////////////////////////1.Socks5 connection request negotiation-Begin//////////////////////
|
||||
//Waiting for connection prompts
|
||||
cout<<"Accepting connection from: localhost"<<endl;
|
||||
//+ serv_addr.sin_addr.s_addr+" "+ serv_addr.sin_port);
|
||||
//Waiting for Client Connection
|
||||
clilen = sizeof(cli_addr);
|
||||
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
|
||||
if (newsockfd < 0) {
|
||||
cout<<"can't bind local address"<<endl;
|
||||
}
|
||||
|
||||
//Get 2 bytes of information from the client
|
||||
// - socks version number, total number of negotiation methods
|
||||
char buf1[1];
|
||||
char buf2[2];
|
||||
char buf4[4];
|
||||
if (recv(newsockfd, buf2, 2, 0) == -1) {
|
||||
cout<<"cannot get version-nmethod"<<endl;
|
||||
}
|
||||
|
||||
if ((uint8_t)buf2[0] != socks_vision) {
|
||||
cout<<"version is wrong"<<endl;
|
||||
close(newsockfd);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((uint8_t)buf2[1] <= 0) {
|
||||
cout<<"nmethod is wrong"<<endl;
|
||||
close(newsockfd);
|
||||
continue;
|
||||
}
|
||||
cout<<"version-nmethod: ";
|
||||
printf("%x ", buf2[0]);
|
||||
printf("%x \n", buf2[1]);
|
||||
//negotiation methods
|
||||
int nmethods = (uint8_t)buf2[1];
|
||||
int flag = 0;
|
||||
|
||||
for (int i = 0; i < nmethods; i++) {
|
||||
recv(newsockfd, buf1, 1, 0);
|
||||
if ((uint8_t)(buf1[0]) == 0) {
|
||||
flag = 1;
|
||||
}
|
||||
cout<<"nmethods: ";
|
||||
printf("%x\n", buf1[0]);
|
||||
}
|
||||
|
||||
if (flag == 0) {
|
||||
cout<<"methods donot have 0"<<endl;
|
||||
close(newsockfd);
|
||||
continue;
|
||||
}
|
||||
|
||||
//Return request reply (no sub-negotiation required)!!!!!!
|
||||
uint8_t msg2[2];
|
||||
msg2[0] = socks_vision;
|
||||
msg2[1] = ui0;
|
||||
|
||||
if (send(newsockfd, msg2, 2, 0) == -1) {
|
||||
cout<<"cannot send socks-methond-reply"<<endl;
|
||||
}
|
||||
//////////////////////////////1.Socks5 connection request negotiation-End//////////////////////
|
||||
|
||||
//////////////////////////////2.Packet parsing of URL requests - Begin//////////////////////
|
||||
//Get the first four bytes of information such as the address type of URL request
|
||||
// from the client
|
||||
if (recv(newsockfd, buf4, 4, 0) == -1) {
|
||||
cout<<"cannot get version-cmd-_-addressType"<<endl;
|
||||
}
|
||||
cout<<"version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
if ((uint8_t)buf4[0] != 5) {
|
||||
cout<<"version is wrong. version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
close(newsockfd);
|
||||
continue;
|
||||
}
|
||||
uint8_t cmd = (uint8_t)buf4[1];
|
||||
uint8_t addressType = (uint8_t)buf4[3];
|
||||
//Get the IP address of the destination server of URL request from the client
|
||||
char* r_address;
|
||||
char* domin_address;
|
||||
|
||||
if (addressType == 1) {//ipv4
|
||||
remote_addr_length=4;
|
||||
r_address=new char[4];
|
||||
if (recv(newsockfd, r_address, 4, 0) == -1) {
|
||||
cout<<"cannot get the ipv4\n"<<endl;
|
||||
}
|
||||
printf("ipv4: %d %d %d %d\n",(uint8_t)r_address[0],(uint8_t)r_address[1],(uint8_t)r_address[2],(uint8_t)r_address[3]);
|
||||
}else{
|
||||
cout<<"not ipv4"<<endl;
|
||||
close(newsockfd);
|
||||
continue;
|
||||
}
|
||||
|
||||
//Listener port of destination server for URL request from client
|
||||
char r_port[2];
|
||||
if (recv(newsockfd, r_port, 2, 0) == -1) {
|
||||
cout<<"cannot get the port\n"<<endl;
|
||||
close(newsockfd);
|
||||
continue;
|
||||
}
|
||||
printf("port: %d %d\n", (uint8_t)r_port[0],(uint8_t)r_port[1]);
|
||||
//////////////////////////////2.Packet parsing of URL requests-End//////////////////////
|
||||
|
||||
//////////////////////////////3.Connect to remote destination server-Begin//////////////////////
|
||||
//When the connection to the remote server is successful,
|
||||
//the rep_flag tag is 0
|
||||
int rep_flag = 5;
|
||||
try
|
||||
{
|
||||
if (cmd == 1) {
|
||||
//Connect to remote destination server
|
||||
remote_sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
bzero((char *)&remote_addr, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
if ((addressType == 1)||(addressType==4)){
|
||||
// remote_addr.sin_addr.s_addr = inet_addr(r_address);
|
||||
memcpy(&(remote_addr.sin_addr.s_addr),r_address,remote_addr_length);
|
||||
}else if(addressType == 3){
|
||||
// remote_addr.sin_addr.s_addr = inet_addr(domin_address);
|
||||
memcpy(&(remote_addr.sin_addr.s_addr),domin_address,remote_addr_length);
|
||||
}
|
||||
|
||||
// remote_addr.sin_port = htons((uint16_t)(long)r_port);
|
||||
memcpy(&(remote_addr.sin_port),r_port,2);
|
||||
cout<<"connecting..."<<endl;
|
||||
int res_c=connect(remote_sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
if(res_c==-1){
|
||||
cout<<"connect error"<<endl;
|
||||
close(newsockfd);
|
||||
close(remote_sockfd);
|
||||
continue;
|
||||
}
|
||||
cout<<"connected"<<endl;
|
||||
|
||||
//Print Successful Connection Tips
|
||||
if (addressType == 1){
|
||||
printf("Connected to %s:%d\n",inet_ntoa(remote_addr.sin_addr),remote_addr.sin_port);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
printf("cmd is not connection");
|
||||
close(newsockfd);
|
||||
continue;
|
||||
}
|
||||
|
||||
//getsocketname()
|
||||
sockaddr_in cs_addr;
|
||||
memset(&cs_addr,0,sizeof(cs_addr));
|
||||
int cs_len=sizeof(cs_addr);
|
||||
int res_sn=getsockname(remote_sockfd,(struct sockaddr *)&cs_addr,(socklen_t *)&cs_len);
|
||||
|
||||
cout<<"Current connection Socket IP:"<<inet_ntoa(cs_addr.sin_addr)<<":"<<ntohs(cs_addr.sin_port)<<endl;
|
||||
|
||||
//Return connection information to client!!!!!
|
||||
uint8_t *connRrt;
|
||||
if(addressType==1){
|
||||
connRrt=new uint8_t[10];
|
||||
connRrt[0]=socks_vision;
|
||||
connRrt[1]=ui0;
|
||||
connRrt[2]=ui0;
|
||||
connRrt[3]=addressType;
|
||||
memcpy(&connRrt[4],&(cs_addr.sin_addr.s_addr),4);
|
||||
memcpy(&connRrt[8],&(cs_addr.sin_port),2);
|
||||
cout<<"the reply ip:"<<endl;
|
||||
for(int i=0;i<4;i++){
|
||||
printf("%d ",(uint8_t)connRrt[4+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
cout<<"the reply port:"<<endl;
|
||||
for(int i=0;i<2;i++){
|
||||
printf("%d ",(uint8_t)connRrt[8+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
}else{}
|
||||
|
||||
if (send(newsockfd, connRrt, 10, 0) == -1) {
|
||||
printf("cannot send url-reply\n");
|
||||
}
|
||||
rep_flag = 0;
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
uint8_t err[6];
|
||||
err[0] = socks_vision;
|
||||
err[1] = ui5;
|
||||
err[2] = ui0;
|
||||
err[3] = addressType;
|
||||
err[4] = ui0;
|
||||
err[5] = ui0;
|
||||
if (send(newsockfd, err, 6, 0) == -1) {
|
||||
printf("cannot send url-err-reply\n");
|
||||
}
|
||||
}
|
||||
//////////////////////////////3.Connect to remote destination server-End//////////////////////
|
||||
|
||||
//////////////////////////////4.Data Exchange (Web Request)-Begin//////////////////////
|
||||
|
||||
if ((cmd == 1) && (rep_flag == 0)) {
|
||||
printf("Data transmission is beginning.\n");
|
||||
// listen to the 9011
|
||||
pthread_t tid1 ;
|
||||
int ret1 = pthread_create(&tid1,NULL,thread_fun1,&remote_sockfd);
|
||||
cout<<"ret1: "<<ret1<<endl;
|
||||
// listen to the remote server
|
||||
pthread_t tid2 ;
|
||||
int ret2 = pthread_create(&tid2,NULL,thread_fun2,&remote_sockfd);
|
||||
cout<<"ret2: "<<ret2<<endl;
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////4.Data Exchange (Web Request)-End//////////////////////
|
||||
}
|
||||
close(sockfd);
|
||||
printf("The sockfd is closed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,372 @@
|
||||
#include "Socks5Server.h"
|
||||
using namespace std;
|
||||
|
||||
// simulate socks5-server
|
||||
// usage:
|
||||
// 1. "g++ -c Socks5Server.cpp"
|
||||
// 2. "g++ -c main.cpp"
|
||||
// 3. "g++ -o sermax main.o Socks5Server.o -lpthread"
|
||||
// 4. "./sermax"
|
||||
// 5. test:
|
||||
// "curl -v --socks5 127.0.0.1:9011 https://www.baidu.com" => ok
|
||||
// make firefox browser port 9011 => ok
|
||||
|
||||
// local port listenner thread
|
||||
void* thread_fun1(void* val);
|
||||
// remote server listenner thread
|
||||
void* thread_fun2(void* val);
|
||||
|
||||
// listen to the local port
|
||||
void Socks5Server::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
|
||||
while( bind(this->sockfd, (struct sockaddr *) &(this->serv_addr), sizeof(this->serv_addr)) < 0){
|
||||
sleep(1) ;
|
||||
cout << "bind fail" << endl ;
|
||||
};
|
||||
listen(this->sockfd,10);
|
||||
};
|
||||
|
||||
// waiting for the local port's connection
|
||||
int Socks5Server::acceptLocal(){
|
||||
int newsockfd;
|
||||
struct sockaddr_in cli_addr;
|
||||
int cli_len=sizeof(cli_addr);
|
||||
cout<<"Waitting connection from localhost..."<<endl;
|
||||
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&cli_len);
|
||||
if (newsockfd < 0) {
|
||||
cout<<"can't bind local address"<<endl;
|
||||
}else{
|
||||
cout<<"Acceptted a connection from localhost"<<endl;
|
||||
}
|
||||
return newsockfd;
|
||||
};
|
||||
|
||||
// a headshake for the sub-negotiation method
|
||||
int Socks5Server::negotShake(int val){
|
||||
// right flag, the loop is going on when th flag==0
|
||||
int flag=0;
|
||||
// newsockfd
|
||||
int newsockfd = val;
|
||||
//Get 2 bytes of information from the client
|
||||
// - socks version number, total number of negotiation methods
|
||||
char buf1[1];
|
||||
char buf2[2];
|
||||
if (recv(newsockfd, buf2, 2, 0) == -1) {
|
||||
cout<<"cannot get version-nmethod"<<endl;
|
||||
}
|
||||
if ((uint8_t)buf2[0] != this->socks_vision) {
|
||||
cout<<"socks version is wrong"<<endl;
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
if ((uint8_t)buf2[1] <= 0) {
|
||||
cout<<"nmethod is wrong"<<endl;
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
cout<<"version-nmethod: ";
|
||||
printf("%x ", buf2[0]);
|
||||
printf("%x \n", buf2[1]);
|
||||
|
||||
//negotiation methods
|
||||
int nmethods = (uint8_t)buf2[1];
|
||||
// the method contains 0 when the m_flag==1
|
||||
int m_flag = 0;
|
||||
for (int i = 0; i < nmethods; i++) {
|
||||
recv(newsockfd, buf1, 1, 0);
|
||||
if ((uint8_t)(buf1[0]) == 0) {
|
||||
m_flag = 1;
|
||||
}
|
||||
cout<<"nmethods: ";
|
||||
printf("%x\n", buf1[0]);
|
||||
}
|
||||
if (m_flag == 0) {
|
||||
cout<<"methods donot have 0"<<endl;
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
//Return request reply (no sub-negotiation required)
|
||||
uint8_t msg2[2];
|
||||
msg2[0] = this->socks_vision;
|
||||
msg2[1] = this->ui0;
|
||||
if (send(newsockfd, msg2, 2, 0) == -1) {
|
||||
cout<<"cannot send socks-methond-reply"<<endl;
|
||||
}
|
||||
|
||||
return flag;
|
||||
};
|
||||
|
||||
// a headshake for the connection information
|
||||
// to remote server
|
||||
pair<int,int> Socks5Server::connShake(int val){
|
||||
// right flag, the loop is going on when th flag==0
|
||||
int flag=0;
|
||||
// newsockfd
|
||||
int newsockfd = val;
|
||||
//Get the first four bytes of information
|
||||
// such as the address type of URL request
|
||||
// from the client
|
||||
char buf4[4];
|
||||
if (recv(newsockfd, buf4, 4, 0) == -1) {
|
||||
cout<<"cannot get version-cmd-_-addressType"<<endl;
|
||||
}
|
||||
cout<<"version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
if ((uint8_t)buf4[0] != 5) {
|
||||
cout<<"version is wrong. version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
return make_pair(1,1);
|
||||
}
|
||||
uint8_t cmd = (uint8_t)buf4[1];
|
||||
if(cmd!=1){
|
||||
cout<<"cmd is not 1"<<endl;
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
return make_pair(1,1);
|
||||
}
|
||||
uint8_t addressType = (uint8_t)buf4[3];
|
||||
|
||||
//Get the IP address of the destination server of URL request from the client
|
||||
char* r_address;
|
||||
char* domin_address;
|
||||
int remote_addr_length=4;
|
||||
if (addressType == 1) {//ipv4
|
||||
r_address=new char[4];
|
||||
if (recv(newsockfd, r_address, 4, 0) == -1) {
|
||||
cout<<"cannot get the ipv4\n"<<endl;
|
||||
}
|
||||
printf("ipv4: %d %d",(uint8_t)r_address[0],(uint8_t)r_address[1]);
|
||||
printf(" %d %d\n",(uint8_t)r_address[2],(uint8_t)r_address[3]);
|
||||
}else{
|
||||
cout<<"address is not ipv4"<<endl;
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
return make_pair(1,1);
|
||||
}
|
||||
|
||||
//Listener port of destination server for URL request from client
|
||||
char r_port[2];
|
||||
if (recv(newsockfd, r_port, 2, 0) == -1) {
|
||||
cout<<"cannot get the port\n"<<endl;
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
return make_pair(1,1);
|
||||
}
|
||||
printf("port: %d %d\n", (uint8_t)r_port[0],(uint8_t)r_port[1]);
|
||||
|
||||
//When the connection to the remote server is successful,
|
||||
// remote server
|
||||
int remote_sockfd;
|
||||
struct sockaddr_in remote_addr;
|
||||
try
|
||||
{
|
||||
if (cmd == 1) {
|
||||
//Connect to remote destination server
|
||||
remote_sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
bzero((char *)&remote_addr, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
if ((addressType == 1)||(addressType==4)){
|
||||
memcpy(&(remote_addr.sin_addr.s_addr),r_address,remote_addr_length);
|
||||
}else if(addressType == 3){
|
||||
memcpy(&(remote_addr.sin_addr.s_addr),domin_address,remote_addr_length);
|
||||
}
|
||||
memcpy(&(remote_addr.sin_port),r_port,2);
|
||||
|
||||
cout<<"connecting..."<<endl;
|
||||
int res_c=connect(remote_sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
if(res_c==-1){
|
||||
cout<<"connect error"<<endl;
|
||||
close(newsockfd);
|
||||
close(remote_sockfd);
|
||||
flag=1;
|
||||
}
|
||||
cout<<"connected"<<endl;
|
||||
|
||||
//Print Successful Connection Tips
|
||||
if (addressType == 1){
|
||||
printf("Connected to %s:%d\n",inet_ntoa(remote_addr.sin_addr),remote_addr.sin_port);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
printf("cmd is not connection\n");
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
}
|
||||
|
||||
//getsocketname()
|
||||
sockaddr_in cs_addr;
|
||||
memset(&cs_addr,0,sizeof(cs_addr));
|
||||
int cs_len=sizeof(cs_addr);
|
||||
int res_sn=getsockname(remote_sockfd,(struct sockaddr *)&cs_addr,(socklen_t *)&cs_len);
|
||||
cout<<"Current connection Socket IP:"<<inet_ntoa(cs_addr.sin_addr)<<":"<<ntohs(cs_addr.sin_port)<<endl;
|
||||
|
||||
//Return connection information to client
|
||||
uint8_t *connRrt;
|
||||
if(addressType==1){
|
||||
connRrt=new uint8_t[10];
|
||||
connRrt[0]=socks_vision;
|
||||
connRrt[1]=ui0;
|
||||
connRrt[2]=ui0;
|
||||
connRrt[3]=addressType;
|
||||
memcpy(&connRrt[4],&(cs_addr.sin_addr.s_addr),4);
|
||||
memcpy(&connRrt[8],&(cs_addr.sin_port),2);
|
||||
cout<<"the reply ip:"<<endl;
|
||||
for(int i=0;i<4;i++){
|
||||
printf("%d ",(uint8_t)connRrt[4+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
cout<<"the reply port:"<<endl;
|
||||
for(int i=0;i<2;i++){
|
||||
printf("%d ",(uint8_t)connRrt[8+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
}else{}
|
||||
|
||||
if (send(newsockfd, connRrt, 10, 0) == -1) {
|
||||
printf("cannot send url-reply\n");
|
||||
flag=1;
|
||||
}
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
uint8_t err[6];
|
||||
err[0] = socks_vision;
|
||||
err[1] = ui5;
|
||||
err[2] = ui0;
|
||||
err[3] = addressType;
|
||||
err[4] = ui0;
|
||||
err[5] = ui0;
|
||||
if (send(newsockfd, err, 6, 0) == -1) {
|
||||
printf("cannot send url-err-reply\n");
|
||||
flag=1;
|
||||
}
|
||||
}
|
||||
return make_pair(remote_sockfd,flag);
|
||||
|
||||
};
|
||||
|
||||
// data transmission shake
|
||||
void Socks5Server::transData(pair<int,int> pairval){
|
||||
int newsockfd = pairval.first;
|
||||
int remote_sockfd = pairval.second;
|
||||
printf("Data transmission is beginning.\n");
|
||||
struct mypara
|
||||
{
|
||||
int para1;//参数1
|
||||
int para2;//参数2
|
||||
};
|
||||
struct mypara pstru={newsockfd,remote_sockfd};
|
||||
// listen to the local port
|
||||
pthread_t tid1 ;
|
||||
int ret1 = pthread_create(&tid1,NULL,thread_fun1,&(pstru));
|
||||
cout<<"thread return1: "<<ret1<<endl;
|
||||
// listen to the remote server
|
||||
pthread_t tid2 ;
|
||||
int ret2 = pthread_create(&tid2,NULL,thread_fun2,&(pstru));
|
||||
cout<<"thread return2: "<<ret2<<endl;
|
||||
};
|
||||
|
||||
// forever listenner function
|
||||
void Socks5Server::forever(){
|
||||
while(true){
|
||||
int newsockfd = this->acceptLocal();
|
||||
if(this->negotShake(newsockfd)>0){
|
||||
cout<<"negotShake error"<<endl;
|
||||
continue;
|
||||
}
|
||||
pair<int,int> pairval=connShake(newsockfd);
|
||||
if(pairval.second>0){
|
||||
cout<<"connShake error"<<endl;
|
||||
continue;
|
||||
}
|
||||
int remote_sockfd = pairval.first;
|
||||
this->transData(make_pair(newsockfd,remote_sockfd));
|
||||
}
|
||||
};
|
||||
|
||||
// server start
|
||||
void Socks5Server::start(){
|
||||
this->listenLocal();
|
||||
this->forever();
|
||||
close(this->sockfd);
|
||||
};
|
||||
|
||||
// transfer data form local port to remote server
|
||||
void * thread_fun1(void* val){
|
||||
struct mypara
|
||||
{
|
||||
int para1;//参数1
|
||||
int para2;//参数2
|
||||
};
|
||||
mypara *pstru;
|
||||
pstru = (struct mypara *) val;
|
||||
// pair<int,int> pairval=*((pair<int,int>*)val);
|
||||
int local_sockfd = pstru->para1;
|
||||
int remote_sockfd= pstru->para2;
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(local_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from local_sock datalen = " << datalen << endl ;
|
||||
if (datalen<= 0) {
|
||||
break ;
|
||||
}else{ // send to remote server
|
||||
send_len = send(remote_sockfd, data, datalen, 0) ;
|
||||
cout << "send to remote_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// transfer data form remote server to local port
|
||||
void * thread_fun2(void* val){
|
||||
struct mypara
|
||||
{
|
||||
int para1;//参数1
|
||||
int para2;//参数2
|
||||
};
|
||||
mypara *pstru;
|
||||
pstru = (struct mypara *) val;
|
||||
// pair<int,int> pairval=*((pair<int,int>*)val);
|
||||
int local_sockfd = pstru->para1;
|
||||
int remote_sockfd= pstru->para2;
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(remote_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from remote_sock datalen = " << datalen << endl ;
|
||||
if (datalen <= 0) {
|
||||
//nothing
|
||||
break;
|
||||
}else{
|
||||
// send to localhost
|
||||
send_len = send(local_sockfd, data, datalen, 0) ;
|
||||
cout << "send to local_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#ifndef SOCKS_H_INCLUDED
|
||||
#define SOCKS_H_INCLUDED
|
||||
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#define SERV_TCP_PORT 9011 /* Local listening port number */
|
||||
#define MAX_SIZE 1024*100
|
||||
#define SOCKS5_VERSION 5
|
||||
using namespace std;
|
||||
|
||||
class Socks5Server{
|
||||
public:
|
||||
// sockfd
|
||||
int sockfd;
|
||||
// sockaddr
|
||||
struct sockaddr_in serv_addr;
|
||||
/* Local listening port number */
|
||||
int port;
|
||||
// socks version
|
||||
uint8_t socks_vision;
|
||||
// 2 commom numbers
|
||||
uint8_t ui0;
|
||||
uint8_t ui5;
|
||||
|
||||
public:
|
||||
// construction function
|
||||
Socks5Server(){
|
||||
this->port=SERV_TCP_PORT;
|
||||
this->ui0=0;
|
||||
this->ui5=5;
|
||||
this->socks_vision=SOCKS5_VERSION;
|
||||
}
|
||||
Socks5Server(int port){
|
||||
this->port=port;
|
||||
this->ui0=0;
|
||||
this->ui5=5;
|
||||
this->socks_vision=SOCKS5_VERSION;
|
||||
}
|
||||
~Socks5Server(){
|
||||
}
|
||||
// listen to the local port
|
||||
void listenLocal();
|
||||
// waiting for the local port's connection
|
||||
int acceptLocal();
|
||||
// a headshake for the sub-negotiation method
|
||||
int negotShake(int val);
|
||||
// a headshake for the connection information
|
||||
// to remote server
|
||||
pair<int,int> connShake(int val);
|
||||
// data transmission shake
|
||||
void transData(pair<int,int> pairval);
|
||||
// forever listenner function
|
||||
void forever();
|
||||
// server start
|
||||
void start();
|
||||
};
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
#include "Socks5Server.h"
|
||||
using namespace std;
|
||||
int main(){
|
||||
// new a server
|
||||
Socks5Server *ss_server=new Socks5Server();
|
||||
// server start
|
||||
ss_server->start();
|
||||
// delete
|
||||
delete ss_server;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,456 @@
|
||||
#include "Socks5Server.h"
|
||||
using namespace std;
|
||||
|
||||
// simulate socks5-server
|
||||
// usage:
|
||||
// 1. "g++ -c Socks5Server.cpp"
|
||||
// 2. "g++ -c main.cpp"
|
||||
// 3. "g++ -o sermax main.o Socks5Server.o -lpthread"
|
||||
// 4. "./sermax"
|
||||
// 5. test:
|
||||
// "curl -v --socks5 127.0.0.1:9011 https://www.baidu.com" => ok
|
||||
// make firefox browser port 9011 => ok
|
||||
// test the ipv6 url:"https://mirrors6.tuna.tsinghua.edu.cn/" => error
|
||||
|
||||
// local port listenner thread
|
||||
void* thread_fun1(void *val);
|
||||
// remote server listenner thread
|
||||
void* thread_fun2(void *val);
|
||||
|
||||
// listen to the local port
|
||||
void Socks5Server::listenLocal(){
|
||||
this->sockfd=socket(AF_INET, SOCK_STREAM, 0);
|
||||
// do following thing so that we can bind our port again
|
||||
// int opt = 1;
|
||||
// int len = sizeof(opt);
|
||||
// while(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, (socklen_t)len)<0){
|
||||
// cout<<"set sockopt error"<<endl;
|
||||
// };
|
||||
/* 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
|
||||
while( bind(this->sockfd, (struct sockaddr *) &(this->serv_addr), sizeof(this->serv_addr)) < 0){
|
||||
sleep(1) ;
|
||||
cout << "bind fail" << endl ;
|
||||
};
|
||||
listen(this->sockfd,10);
|
||||
};
|
||||
|
||||
// waiting for the local port's connection
|
||||
int Socks5Server::acceptLocal(){
|
||||
int newsockfd;
|
||||
struct sockaddr_in cli_addr;
|
||||
int cli_len=sizeof(cli_addr);
|
||||
cout<<"Waitting connection from localhost..."<<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 from localhost"<<endl;
|
||||
|
||||
return newsockfd;
|
||||
};
|
||||
|
||||
// a headshake for the sub-negotiation method
|
||||
int Socks5Server::negotShake(int val){
|
||||
// right flag, the loop is going on when th flag==0
|
||||
int flag=0;
|
||||
// newsockfd
|
||||
int newsockfd = val;
|
||||
//Get 2 bytes of information from the client
|
||||
// - socks version number, total number of negotiation methods
|
||||
char buf1[1];
|
||||
char buf2[2];
|
||||
if (recv(newsockfd, buf2, 2, 0) == -1) {
|
||||
cout<<"cannot get version-nmethod"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
if ((uint8_t)buf2[0] != this->socks_vision) {
|
||||
cout<<"socks version is wrong"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
if ((uint8_t)buf2[1] <= 0) {
|
||||
cout<<"nmethod is wrong"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
cout<<"version-nmethod: ";
|
||||
printf("%x ", buf2[0]);
|
||||
printf("%x \n", buf2[1]);
|
||||
|
||||
//negotiation methods
|
||||
int nmethods = (uint8_t)buf2[1];
|
||||
// the method contains 0 when the m_flag==1
|
||||
int m_flag = 0;
|
||||
for (int i = 0; i < nmethods; i++) {
|
||||
recv(newsockfd, buf1, 1, 0);
|
||||
if ((uint8_t)(buf1[0]) == 0) {
|
||||
m_flag = 1;
|
||||
}
|
||||
cout<<"nmethods: ";
|
||||
printf("%x\n", buf1[0]);
|
||||
}
|
||||
if (m_flag == 0) {
|
||||
cout<<"methods donot have 0"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
//Return request reply (no sub-negotiation required)
|
||||
uint8_t msg2[2];
|
||||
msg2[0] = this->socks_vision;
|
||||
msg2[1] = this->ui0;
|
||||
if (send(newsockfd, msg2, 2, 0) == -1) {
|
||||
cout<<"cannot send socks-methond-reply"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
return flag;
|
||||
};
|
||||
|
||||
// a headshake for the connection information
|
||||
// to remote server
|
||||
pair<int,int> Socks5Server::connShake(int val){
|
||||
// right flag, the loop is going on when th flag==0
|
||||
int flag=0;
|
||||
// newsockfd
|
||||
int newsockfd = val;
|
||||
//Get the first four bytes of information
|
||||
// such as the address type of URL request
|
||||
// from the client
|
||||
char buf4[4];
|
||||
if (recv(newsockfd, buf4, 4, 0) == -1) {
|
||||
cout<<"cannot get version-cmd-_-addressType"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
cout<<"version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
if ((uint8_t)buf4[0] != 5) {
|
||||
cout<<"version is wrong. version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
uint8_t cmd = (uint8_t)buf4[1];
|
||||
if(cmd!=1){
|
||||
cout<<"cmd is not 1"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
uint8_t addressType = (uint8_t)buf4[3];
|
||||
if(addressType!=1){
|
||||
cout<<"address is not ipv4"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
|
||||
//Get the IP address of the destination server of URL request from the client
|
||||
char* r_address;
|
||||
char* domin_address;
|
||||
int remote_addr_length=4;
|
||||
if (addressType == 1) {//ipv4
|
||||
remote_addr_length=4;
|
||||
r_address=new char[4];
|
||||
if (recv(newsockfd, r_address, 4, 0) == -1) {
|
||||
cout<<"cannot get the ipv4\n"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
printf("ipv4: %d %d",(uint8_t)r_address[0],(uint8_t)r_address[1]);
|
||||
printf(" %d %d\n",(uint8_t)r_address[2],(uint8_t)r_address[3]);
|
||||
}else if(addressType==4){//ipv6 => error. killed by me in early code
|
||||
remote_addr_length=16;
|
||||
r_address=new char[16];
|
||||
if (recv(newsockfd, r_address, 16, 0) == -1) {
|
||||
cout<<"cannot get the ipv6\n"<<endl;
|
||||
}
|
||||
printf("ipv6: (...)\n");
|
||||
}else{
|
||||
cout<<"address is not ipv4 or ipv6"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
|
||||
//Listener port of destination server for URL request from client
|
||||
char r_port[2];
|
||||
if (recv(newsockfd, r_port, 2, 0) == -1) {
|
||||
cout<<"cannot get the port\n"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
printf("port: %d %d\n", (uint8_t)r_port[0],(uint8_t)r_port[1]);
|
||||
|
||||
//When the connection to the remote server is successful,
|
||||
// remote server
|
||||
int remote_sockfd;
|
||||
try
|
||||
{
|
||||
if (cmd == 1) {
|
||||
if (addressType == 1){//ipv4
|
||||
//Connect to remote destination server
|
||||
struct sockaddr_in remote_addr;
|
||||
remote_sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
bzero((char *)&remote_addr, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
memcpy(&(remote_addr.sin_addr.s_addr),r_address,remote_addr_length);
|
||||
memcpy(&(remote_addr.sin_port),r_port,2);
|
||||
cout<<"connecting to ipv4..."<<endl;
|
||||
int res_c=connect(remote_sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
if(res_c==-1){
|
||||
cout<<"connect error"<<endl;
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}else{
|
||||
cout<<"connected ipv6"<<endl;
|
||||
printf("Connected to %s:%d\n",inet_ntoa(remote_addr.sin_addr),remote_addr.sin_port);
|
||||
}
|
||||
}else if(addressType == 4){//ipv6 => error
|
||||
//Connect to remote destination server
|
||||
struct sockaddr_in6 remote_addr;
|
||||
remote_sockfd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
bzero((char *)&remote_addr, sizeof(remote_addr));
|
||||
remote_addr.sin6_family = AF_INET6;
|
||||
memcpy(&(remote_addr.sin6_addr.__in6_u.__u6_addr8),r_address,remote_addr_length);
|
||||
memcpy(&(remote_addr.sin6_port),r_port,2);
|
||||
cout<<"connecting to ipv6..."<<endl;
|
||||
int res_c=connect(remote_sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
if(res_c==-1){
|
||||
cout<<"connect error"<<endl;
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}else{
|
||||
cout<<"connected ipv6"<<endl;
|
||||
// printf("Connected to %s:%d\n",remote_addr.sin6_addr.__in6_u.__u6_addr8,remote_addr.sin6_port);
|
||||
}
|
||||
}else{
|
||||
//...
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
printf("cmd is not connection\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
|
||||
//Return connection information to client
|
||||
uint8_t *connRrt;
|
||||
if(addressType==1){//ipv4
|
||||
//getsocketname()
|
||||
sockaddr_in cs_addr;
|
||||
memset(&cs_addr,0,sizeof(cs_addr));
|
||||
int cs_len=sizeof(cs_addr);
|
||||
int res_sn=getsockname(remote_sockfd,(struct sockaddr *)&cs_addr,(socklen_t *)&cs_len);
|
||||
cout<<"Current connection:"<<inet_ntoa(cs_addr.sin_addr)<<":"<<ntohs(cs_addr.sin_port)<<endl;
|
||||
// return info
|
||||
connRrt=new uint8_t[10];
|
||||
connRrt[0]=socks_vision;
|
||||
connRrt[1]=ui0;
|
||||
connRrt[2]=ui0;
|
||||
connRrt[3]=addressType;
|
||||
memcpy(&connRrt[4],&(cs_addr.sin_addr.s_addr),remote_addr_length);
|
||||
memcpy(&connRrt[8],&(cs_addr.sin_port),2);
|
||||
cout<<"the reply ip:"<<endl;
|
||||
for(int i=0;i<4;i++){
|
||||
printf("%d ",(uint8_t)connRrt[4+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
cout<<"the reply port:"<<endl;
|
||||
for(int i=0;i<2;i++){
|
||||
printf("%d ",(uint8_t)connRrt[8+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
if (send(newsockfd, connRrt, 10, 0) == -1) {
|
||||
printf("cannot send url-reply\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
}else if(addressType==4){//ipv6 => error
|
||||
// getsocketname()
|
||||
sockaddr_in6 cs_addr;
|
||||
memset(&cs_addr,0,sizeof(cs_addr));
|
||||
int cs_len=sizeof(cs_addr);
|
||||
int res_sn=getsockname(remote_sockfd,(struct sockaddr *)&cs_addr,(socklen_t *)&cs_len);
|
||||
cout<<"Current connection:"<<"(ipv6...)"<<":"<<ntohs(cs_addr.sin6_port)<<endl;
|
||||
// return info
|
||||
connRrt=new uint8_t[22];
|
||||
connRrt[0]=socks_vision;
|
||||
connRrt[1]=ui0;
|
||||
connRrt[2]=ui0;
|
||||
connRrt[3]=addressType;
|
||||
memcpy(&connRrt[4],&(cs_addr.sin6_addr.__in6_u.__u6_addr8),remote_addr_length);
|
||||
memcpy(&connRrt[20],&(cs_addr.sin6_port),2);
|
||||
cout<<"the reply ip:"<<endl;
|
||||
for(int i=0;i<16;i++){
|
||||
printf("%d ",(uint8_t)connRrt[4+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
cout<<"the reply port:"<<endl;
|
||||
for(int i=0;i<2;i++){
|
||||
printf("%d ",(uint8_t)connRrt[20+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
if (send(newsockfd, connRrt, 22, 0) == -1) {
|
||||
printf("cannot send url-reply\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
}else{}
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
uint8_t err[6];
|
||||
err[0] = socks_vision;
|
||||
err[1] = ui5;
|
||||
err[2] = ui0;
|
||||
err[3] = addressType;
|
||||
err[4] = ui0;
|
||||
err[5] = ui0;
|
||||
if (send(newsockfd, err, 6, 0) == -1) {
|
||||
printf("cannot send url-err-reply\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
}
|
||||
return make_pair(remote_sockfd,flag);
|
||||
|
||||
};
|
||||
|
||||
// data transmission shake
|
||||
void Socks5Server::transData(pair<int,int> pairval){
|
||||
int newsockfd = pairval.first;
|
||||
int remote_sockfd = pairval.second;
|
||||
printf("Data transmission is beginning.\n");
|
||||
|
||||
int sockfds[2] = {newsockfd,remote_sockfd};
|
||||
|
||||
pid_t fpid1;
|
||||
while ( ( fpid1 = fork() ) < 0 ){
|
||||
cout << "create child process 1 failture! Next will retry!" << endl;
|
||||
}
|
||||
if ( 0 == fpid1 ) {
|
||||
cout<<"子进程1 beginning: "<<endl;
|
||||
thread_fun1(sockfds);
|
||||
cout<<"子进程1 exit()"<<endl;
|
||||
// close the fd in the son process
|
||||
close(this->sockfd);
|
||||
// exit the son process
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pid_t fpid2;
|
||||
while ( ( fpid2 = fork() ) < 0 ){
|
||||
cout << "create child process 2 failture! Next will retry!" << endl;
|
||||
}
|
||||
if ( 0 == fpid2 ) {
|
||||
cout<<"子进程2 beginning: "<<endl;
|
||||
thread_fun2(sockfds);
|
||||
cout<<"子进程2 exit()"<<endl;
|
||||
// close the fd in the son process
|
||||
close(this->sockfd);
|
||||
// exit the son process
|
||||
exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
// forever listenner function
|
||||
void Socks5Server::forever(){
|
||||
while(true){
|
||||
int newsockfd = this->acceptLocal();
|
||||
if(this->negotShake(newsockfd)>0){
|
||||
cout<<"negotShake error"<<endl;
|
||||
close(newsockfd);
|
||||
continue;
|
||||
}
|
||||
pair<int,int> pairval=connShake(newsockfd);
|
||||
if(pairval.second>0){
|
||||
cout<<"connShake error"<<endl;
|
||||
close(newsockfd);
|
||||
if(pairval.first>0){
|
||||
close(pairval.first);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int remote_sockfd = pairval.first;
|
||||
this->transData(make_pair(newsockfd,remote_sockfd));
|
||||
// close the fds in main process
|
||||
close(newsockfd);
|
||||
close(remote_sockfd);
|
||||
}
|
||||
};
|
||||
|
||||
// server start
|
||||
void Socks5Server::start(){
|
||||
this->listenLocal();
|
||||
this->forever();
|
||||
close(this->sockfd);
|
||||
};
|
||||
|
||||
// transfer data form local port to remote server
|
||||
void * thread_fun1(void *val){
|
||||
//pair<int,int> pairval=*((pair<int,int>*)val);
|
||||
int local_sockfd = ((int*)val)[0];
|
||||
int remote_sockfd = ((int*)val)[1];
|
||||
|
||||
// cout << local_sockfd << " ==== " << remote_sockfd << endl;
|
||||
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(local_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from local_sock datalen = " << datalen << endl ;
|
||||
if (datalen<= 0) {
|
||||
|
||||
break ;
|
||||
}else{ // send to remote server
|
||||
send_len = send(remote_sockfd, data, datalen, 0) ;
|
||||
cout << "send to remote_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// transfer data form remote server to local port
|
||||
void * thread_fun2(void *val){
|
||||
//pair<int,int> pairval=*((pair<int,int>*)val);
|
||||
int local_sockfd = ((int*)val)[0];
|
||||
int remote_sockfd = ((int*)val)[1];
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(remote_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from remote_sock datalen = " << datalen << endl ;
|
||||
if (datalen <= 0) {
|
||||
//nothing
|
||||
break;
|
||||
}else{
|
||||
// send to localhost
|
||||
send_len = send(local_sockfd, data, datalen, 0) ;
|
||||
cout << "send to local_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifndef SOCKS_H_INCLUDED
|
||||
#define SOCKS_H_INCLUDED
|
||||
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sys/time.h>
|
||||
// #include <pthread.h>
|
||||
|
||||
#define SERV_TCP_PORT 9011 /* Local listening port number */
|
||||
#define MAX_SIZE 1024*7120
|
||||
#define SOCKS5_VERSION 5
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Socks5Server{
|
||||
public:
|
||||
// sockfd
|
||||
int sockfd;
|
||||
// sockaddr
|
||||
struct sockaddr_in serv_addr;
|
||||
/* Local listening port number */
|
||||
int port;
|
||||
// socks version
|
||||
uint8_t socks_vision;
|
||||
// 2 commom numbers
|
||||
uint8_t ui0;
|
||||
uint8_t ui5;
|
||||
|
||||
public:
|
||||
// construction function
|
||||
Socks5Server(){
|
||||
this->port=SERV_TCP_PORT;
|
||||
this->ui0=0;
|
||||
this->ui5=5;
|
||||
this->socks_vision=SOCKS5_VERSION;
|
||||
}
|
||||
Socks5Server(int port){
|
||||
this->port=port;
|
||||
this->ui0=0;
|
||||
this->ui5=5;
|
||||
this->socks_vision=SOCKS5_VERSION;
|
||||
}
|
||||
~Socks5Server(){
|
||||
}
|
||||
// listen to the local port
|
||||
void listenLocal();
|
||||
// waiting for the local port's connection
|
||||
int acceptLocal();
|
||||
// a headshake for the sub-negotiation method
|
||||
int negotShake(int val);
|
||||
// a headshake for the connection information
|
||||
// to remote server
|
||||
pair<int,int> connShake(int val);
|
||||
// data transmission shake
|
||||
void transData(pair<int,int> pairval);
|
||||
// forever listenner function
|
||||
void forever();
|
||||
// server start
|
||||
void start();
|
||||
};
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
||||
#include "Socks5Server.h"
|
||||
// #include "Socks5Server.cpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(){
|
||||
// new a server
|
||||
Socks5Server *ss_server=new Socks5Server();
|
||||
|
||||
// server start
|
||||
ss_server->start();
|
||||
|
||||
// delete
|
||||
delete ss_server;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,186 @@
|
||||
// simulate socks5-client. coding by wefree in 2019.08
|
||||
#include "Client.h"
|
||||
using namespace std;
|
||||
|
||||
// local port listenner thread
|
||||
void* thread_fun1(void *val);
|
||||
// remote server listenner thread
|
||||
void* thread_fun2(void *val);
|
||||
|
||||
// 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
|
||||
while( bind(this->sockfd, (struct sockaddr *) &(this->serv_addr), sizeof(this->serv_addr)) < 0){
|
||||
sleep(1) ;
|
||||
cout << "bind fail" << endl ;
|
||||
};
|
||||
listen(this->sockfd,10);
|
||||
};
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
// data transmission shake
|
||||
void Client::transData(pair<int,int> pairval){
|
||||
int newsockfd = pairval.first;
|
||||
int remote_sockfd = pairval.second;
|
||||
printf("Data transmission is beginning.\n");
|
||||
|
||||
int sockfds[2] = {newsockfd,remote_sockfd};
|
||||
|
||||
pid_t fpid1;
|
||||
while ( ( fpid1 = fork() ) < 0 ){
|
||||
cout << "create child process 1 failled. Retry..." << endl;
|
||||
}
|
||||
if ( 0 == fpid1 ) {
|
||||
cout<<" child process 1 beginning: "<<endl;
|
||||
thread_fun1(sockfds);
|
||||
cout<<" child process 1 exit()"<<endl;
|
||||
// close the fd in the son process
|
||||
close(this->sockfd);
|
||||
// exit the son process
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pid_t fpid2;
|
||||
while ( ( fpid2 = fork() ) < 0 ){
|
||||
cout << "create child process 2 failled. Retry..." << endl;
|
||||
}
|
||||
if ( 0 == fpid2 ) {
|
||||
cout<<" child process 2 beginning: "<<endl;
|
||||
thread_fun2(sockfds);
|
||||
cout<<" child process 2 exit()"<<endl;
|
||||
// close the fd in the son process
|
||||
close(this->sockfd);
|
||||
// exit the son process
|
||||
exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
int Client::connSockes5Server(){
|
||||
//Connect to remote destination server
|
||||
struct sockaddr_in remote_addr;
|
||||
int socks5_sockfd;
|
||||
socks5_sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
bzero((char *)&remote_addr, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
remote_addr.sin_addr.s_addr=inet_addr(SOCKS5_SERVER_IP);
|
||||
remote_addr.sin_port=htons(SOCKS5_SERVER_PORT);
|
||||
cout<<"connecting to socks5server..."<<endl;
|
||||
int res_c=connect(socks5_sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
while(res_c<0){
|
||||
cout<<"can not connect to the socks server...."<<endl;
|
||||
sleep(1);
|
||||
res_c=connect(socks5_sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
}
|
||||
cout<<"connected socks5server"<<endl;
|
||||
printf("Connected to %s:%d\n",inet_ntoa(remote_addr.sin_addr),remote_addr.sin_port);
|
||||
return socks5_sockfd;
|
||||
}
|
||||
|
||||
// forever listenner function
|
||||
void Client::forever(){
|
||||
while(true){
|
||||
int newsockfd = this->acceptLocal();
|
||||
int socks5_sockfd=this->connSockes5Server() ;
|
||||
this->transData(make_pair(newsockfd,socks5_sockfd));
|
||||
// close the fds in main process
|
||||
close(newsockfd);
|
||||
close(socks5_sockfd);
|
||||
}
|
||||
};
|
||||
|
||||
// server start
|
||||
void Client::start(){
|
||||
this->listenLocal();
|
||||
this->forever();
|
||||
close(this->sockfd);
|
||||
};
|
||||
|
||||
// transfer data form local port to socks5 server
|
||||
void * thread_fun1(void *val){
|
||||
//pair<int,int> pairval=*((pair<int,int>*)val);
|
||||
int local_sockfd = ((int*)val)[0];
|
||||
int socks_sockfd = ((int*)val)[1];
|
||||
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(local_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from local_sock datalen = " << datalen << endl ;
|
||||
if (datalen<= 0) {
|
||||
// 发送一个特殊数据到代理服务器,提醒其关闭此次连接=>也可以设置心跳包来实现
|
||||
// 由于这里正常情况下传输的是http格式数据,因此这种特殊数据不会跟不同数据混同
|
||||
char closedata[10];
|
||||
string closedata_s="closesocks";
|
||||
strcpy(closedata,closedata_s.c_str());
|
||||
send_len = send(socks_sockfd, closedata, 10, 0) ;
|
||||
cout << "send to socks_sockfd the 'closesocks', len = " << send_len << endl ;
|
||||
break ;
|
||||
}else{ // send to socks5 server
|
||||
send_len = send(socks_sockfd, data, datalen, 0) ;
|
||||
cout << "send to socks_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(socks_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// transfer data form socks5 server to local port
|
||||
void * thread_fun2(void *val){
|
||||
//pair<int,int> pairval=*((pair<int,int>*)val);
|
||||
int local_sockfd = ((int*)val)[0];
|
||||
int socks_sockfd = ((int*)val)[1];
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(socks_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from socks_sock datalen = " << datalen << endl ;
|
||||
if (datalen <= 0) {
|
||||
//nothing to do
|
||||
break;
|
||||
}else if(datalen==10){
|
||||
// cout<<"data[10]: "<<data<<endl;
|
||||
string data_len10(data,data+10);
|
||||
if(data_len10=="closesocks"){
|
||||
break;
|
||||
}else{
|
||||
// send to localhost
|
||||
send_len = send(local_sockfd, data, datalen, 0) ;
|
||||
cout << "send to local_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}else{
|
||||
// send to localhost
|
||||
send_len = send(local_sockfd, data, datalen, 0) ;
|
||||
cout << "send to local_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(socks_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef SOCKS_H_INCLUDED
|
||||
#define SOCKS_H_INCLUDED
|
||||
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define SERV_TCP_PORT 8888 /* Local listening port number */
|
||||
#define MAX_SIZE 1024*7120
|
||||
|
||||
// the address of socks server
|
||||
#define SOCKS5_SERVER_IP "127.0.0.1"
|
||||
#define SOCKS5_SERVER_PORT 9011
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Client{
|
||||
private:
|
||||
// sockfd
|
||||
int sockfd;
|
||||
// sockaddr
|
||||
struct sockaddr_in serv_addr;
|
||||
/* Local listening port number */
|
||||
int port;
|
||||
public:
|
||||
// construction function
|
||||
Client(){
|
||||
this->port=SERV_TCP_PORT;
|
||||
}
|
||||
Client(int port){
|
||||
this->port=port;
|
||||
}
|
||||
~Client(){
|
||||
}
|
||||
// listen to the local port
|
||||
void listenLocal();
|
||||
// waiting for the local port's connection
|
||||
int acceptLocal();
|
||||
// connect to the socks server
|
||||
int connSockes5Server();
|
||||
// data transmission shake
|
||||
void transData(pair<int,int> pairval);
|
||||
// forever listenner function
|
||||
void forever();
|
||||
// server start
|
||||
void start();
|
||||
};
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,26 @@
|
||||
#include "Client.h"
|
||||
using namespace std;
|
||||
|
||||
// simulate socks5-client
|
||||
// usage:
|
||||
// 1. "g++ -c Client.cpp"
|
||||
// 2. "g++ -c ClientMain.cpp"
|
||||
// 3. "g++ -o client ClientMain.o Client.o"
|
||||
// 4. "./client"
|
||||
// 5. test:
|
||||
// "curl -v --socks5 127.0.0.1:8888 https://www.baidu.com" => ok
|
||||
// make firefox browser port 8888 => ok
|
||||
|
||||
int main(){
|
||||
Client *client=new Client();
|
||||
client->start();
|
||||
delete client;
|
||||
}
|
||||
|
||||
// makefile:
|
||||
// client: Client.o ClientMain.o
|
||||
// g++ -o client ClientMain.o Client.o
|
||||
// Client.o : Client.cpp Client.h
|
||||
// g++ -c Client.cpp
|
||||
// ClientMain.o : ClientMain.cpp
|
||||
// g++ -c ClientMain.cpp
|
||||
Binary file not shown.
@@ -0,0 +1,27 @@
|
||||
#include "Socks5Server.h"
|
||||
using namespace std;
|
||||
|
||||
// simulate socks5-server
|
||||
// usage:
|
||||
// 1. "g++ -c Socks5Server.cpp"
|
||||
// 2. "g++ -c ServerMain.cpp"
|
||||
// 3. "g++ -o server ServerMain.o Socks5Server.o"
|
||||
// 4. "./server"
|
||||
// 5. test:
|
||||
// "curl -v --socks5 127.0.0.1:9011 https://www.baidu.com" => ok
|
||||
// make firefox browser port 9011 => ok
|
||||
|
||||
int main(){
|
||||
Socks5Server *ss_server=new Socks5Server();
|
||||
ss_server->start();
|
||||
delete ss_server;
|
||||
}
|
||||
|
||||
|
||||
// makefile:
|
||||
// server : Socks5Server.o ServerMain.o
|
||||
// g++ -o server ServerMain.o Socks5Server.o
|
||||
// Socks5Server.o : Socks5Server.cpp Socks5Server.h
|
||||
// g++ -c Socks5Server.cpp
|
||||
// ServerMain.o : ServerMain.cpp
|
||||
// g++ -c ServerMain.cpp
|
||||
Binary file not shown.
@@ -0,0 +1,400 @@
|
||||
// simulate socks5-server. coding by wefree in 2019.08
|
||||
#include "Socks5Server.h"
|
||||
using namespace std;
|
||||
|
||||
// local port listenner thread
|
||||
void* thread_fun1(void *val);
|
||||
// remote server listenner thread
|
||||
void* thread_fun2(void *val);
|
||||
|
||||
// listen to the local port
|
||||
void Socks5Server::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
|
||||
while( bind(this->sockfd, (struct sockaddr *) &(this->serv_addr), sizeof(this->serv_addr)) < 0){
|
||||
sleep(1) ;
|
||||
cout << "bind fail" << endl ;
|
||||
};
|
||||
listen(this->sockfd,10);
|
||||
};
|
||||
|
||||
// waiting for the local port's connection
|
||||
int Socks5Server::acceptLocal(){
|
||||
int newsockfd;
|
||||
struct sockaddr_in cli_addr;
|
||||
int cli_len=sizeof(cli_addr);
|
||||
cout<<"Waitting connection [socks5 server] ..."<<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 [socks5 server]"<<endl;
|
||||
|
||||
return newsockfd;
|
||||
};
|
||||
|
||||
// a headshake for the sub-negotiation method
|
||||
int Socks5Server::negotShake(int val){
|
||||
// right flag, the loop is going on when th flag==0
|
||||
int flag=0;
|
||||
// newsockfd
|
||||
int newsockfd = val;
|
||||
//Get 2 bytes of information from the client
|
||||
// - socks version number, total number of negotiation methods
|
||||
char buf1[1];
|
||||
char buf2[2];
|
||||
if (recv(newsockfd, buf2, 2, 0) == -1) {
|
||||
cout<<"cannot get version-nmethod"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
if ((uint8_t)buf2[0] != this->socks_vision) {
|
||||
cout<<"socks version is wrong"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
if ((uint8_t)buf2[1] <= 0) {
|
||||
cout<<"nmethod is wrong"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
cout<<"version-nmethod: ";
|
||||
printf("%x ", buf2[0]);
|
||||
printf("%x \n", buf2[1]);
|
||||
|
||||
//negotiation methods
|
||||
int nmethods = (uint8_t)buf2[1];
|
||||
// the method contains 0 when the m_flag==1
|
||||
int m_flag = 0;
|
||||
for (int i = 0; i < nmethods; i++) {
|
||||
recv(newsockfd, buf1, 1, 0);
|
||||
if ((uint8_t)(buf1[0]) == 0) {
|
||||
m_flag = 1;
|
||||
}
|
||||
cout<<"nmethods: ";
|
||||
printf("%x\n", buf1[0]);
|
||||
}
|
||||
if (m_flag == 0) {
|
||||
cout<<"methods donot have 0"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
//Return request reply (no sub-negotiation required)
|
||||
uint8_t msg2[2];
|
||||
msg2[0] = this->socks_vision;
|
||||
msg2[1] = this->ui0;
|
||||
if (send(newsockfd, msg2, 2, 0) == -1) {
|
||||
cout<<"cannot send socks-methond-reply"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
return flag;
|
||||
};
|
||||
|
||||
// a headshake for the connection information
|
||||
// to remote server
|
||||
pair<int,int> Socks5Server::connShake(int val){
|
||||
// right flag, the loop is going on when th flag==0
|
||||
int flag=0;
|
||||
// newsockfd
|
||||
int newsockfd = val;
|
||||
//Get the first four bytes of information
|
||||
// such as the address type of URL request
|
||||
// from the client
|
||||
char buf4[4];
|
||||
if (recv(newsockfd, buf4, 4, 0) == -1) {
|
||||
cout<<"cannot get version-cmd-_-addressType"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
cout<<"version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
if ((uint8_t)buf4[0] != 5) {
|
||||
cout<<"version is wrong. version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
uint8_t cmd = (uint8_t)buf4[1];
|
||||
if(cmd!=1){
|
||||
cout<<"cmd is not 1"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
uint8_t addressType = (uint8_t)buf4[3];
|
||||
if(addressType!=1){
|
||||
cout<<"address is not ipv4"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
|
||||
//Get the IP address of the destination server of URL request from the client
|
||||
char* r_address;
|
||||
char* domin_address;
|
||||
int remote_addr_length=4;
|
||||
if (addressType == 1) {//ipv4
|
||||
remote_addr_length=4;
|
||||
r_address=new char[4];
|
||||
if (recv(newsockfd, r_address, 4, 0) == -1) {
|
||||
cout<<"cannot get the ipv4\n"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
printf("ipv4: %d %d",(uint8_t)r_address[0],(uint8_t)r_address[1]);
|
||||
printf(" %d %d\n",(uint8_t)r_address[2],(uint8_t)r_address[3]);
|
||||
}else{
|
||||
cout<<"address is not ipv4"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
|
||||
//Listener port of destination server for URL request from client
|
||||
char r_port[2];
|
||||
if (recv(newsockfd, r_port, 2, 0) == -1) {
|
||||
cout<<"cannot get the port\n"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
printf("port: %d %d\n", (uint8_t)r_port[0],(uint8_t)r_port[1]);
|
||||
|
||||
//When the connection to the remote server is successful,
|
||||
// remote server
|
||||
int remote_sockfd;
|
||||
try
|
||||
{
|
||||
if (cmd == 1) {
|
||||
if (addressType == 1){//ipv4
|
||||
//Connect to remote destination server
|
||||
struct sockaddr_in remote_addr;
|
||||
remote_sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
bzero((char *)&remote_addr, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
memcpy(&(remote_addr.sin_addr.s_addr),r_address,remote_addr_length);
|
||||
memcpy(&(remote_addr.sin_port),r_port,2);
|
||||
cout<<"connecting to ipv4..."<<endl;
|
||||
int res_c=connect(remote_sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
if(res_c==-1){
|
||||
cout<<"connect error"<<endl;
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}else{
|
||||
cout<<"connected ipv6"<<endl;
|
||||
printf("Connected to %s:%d\n",inet_ntoa(remote_addr.sin_addr),remote_addr.sin_port);
|
||||
}
|
||||
}else{
|
||||
//...
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
printf("cmd is not connection\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
|
||||
//Return connection information to client
|
||||
uint8_t *connRrt;
|
||||
if(addressType==1){//ipv4
|
||||
//getsocketname()
|
||||
sockaddr_in cs_addr;
|
||||
memset(&cs_addr,0,sizeof(cs_addr));
|
||||
int cs_len=sizeof(cs_addr);
|
||||
int res_sn=getsockname(remote_sockfd,(struct sockaddr *)&cs_addr,(socklen_t *)&cs_len);
|
||||
cout<<"Current connection:"<<inet_ntoa(cs_addr.sin_addr)<<":"<<ntohs(cs_addr.sin_port)<<endl;
|
||||
// return info
|
||||
connRrt=new uint8_t[10];
|
||||
connRrt[0]=socks_vision;
|
||||
connRrt[1]=ui0;
|
||||
connRrt[2]=ui0;
|
||||
connRrt[3]=addressType;
|
||||
memcpy(&connRrt[4],&(cs_addr.sin_addr.s_addr),remote_addr_length);
|
||||
memcpy(&connRrt[8],&(cs_addr.sin_port),2);
|
||||
cout<<"the reply ip:"<<endl;
|
||||
for(int i=0;i<4;i++){
|
||||
printf("%d ",(uint8_t)connRrt[4+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
cout<<"the reply port:"<<endl;
|
||||
for(int i=0;i<2;i++){
|
||||
printf("%d ",(uint8_t)connRrt[8+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
if (send(newsockfd, connRrt, 10, 0) == -1) {
|
||||
printf("cannot send url-reply\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
}else{}
|
||||
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
uint8_t err[6];
|
||||
err[0] = socks_vision;
|
||||
err[1] = ui5;
|
||||
err[2] = ui0;
|
||||
err[3] = addressType;
|
||||
err[4] = ui0;
|
||||
err[5] = ui0;
|
||||
if (send(newsockfd, err, 6, 0) == -1) {
|
||||
printf("cannot send url-err-reply\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
}
|
||||
return make_pair(remote_sockfd,flag);
|
||||
|
||||
};
|
||||
|
||||
// data transmission shake
|
||||
void Socks5Server::transData(pair<int,int> pairval){
|
||||
int newsockfd = pairval.first;
|
||||
int remote_sockfd = pairval.second;
|
||||
printf("Data transmission is beginning.\n");
|
||||
|
||||
int sockfds[2] = {newsockfd,remote_sockfd};
|
||||
|
||||
pid_t fpid1;
|
||||
while ( ( fpid1 = fork() ) < 0 ){
|
||||
cout << "create child process 1 failled. Retry..." << endl;
|
||||
}
|
||||
if ( 0 == fpid1 ) {
|
||||
cout<<"child process 1 beginning: "<<endl;
|
||||
thread_fun1(sockfds);
|
||||
cout<<"child process 1 exit()"<<endl;
|
||||
// close the fd in the son process
|
||||
close(this->sockfd);
|
||||
// exit the son process
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pid_t fpid2;
|
||||
while ( ( fpid2 = fork() ) < 0 ){
|
||||
cout << "create child process 2 failled. Retry..." << endl;
|
||||
}
|
||||
if ( 0 == fpid2 ) {
|
||||
cout<<"child process 2 beginning: "<<endl;
|
||||
thread_fun2(sockfds);
|
||||
cout<<"child process 2 exit()"<<endl;
|
||||
// close the fd in the son process
|
||||
close(this->sockfd);
|
||||
// exit the son process
|
||||
exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
// forever listenner function
|
||||
void Socks5Server::forever(){
|
||||
while(true){
|
||||
int newsockfd = this->acceptLocal();
|
||||
if(this->negotShake(newsockfd)>0){
|
||||
cout<<"negotShake error"<<endl;
|
||||
close(newsockfd);
|
||||
continue;
|
||||
}
|
||||
pair<int,int> pairval=connShake(newsockfd);
|
||||
if(pairval.second>0){
|
||||
cout<<"connShake error"<<endl;
|
||||
close(newsockfd);
|
||||
if(pairval.first>0){
|
||||
close(pairval.first);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int remote_sockfd = pairval.first;
|
||||
this->transData(make_pair(newsockfd,remote_sockfd));
|
||||
// close the fds in main process
|
||||
close(newsockfd);
|
||||
close(remote_sockfd);
|
||||
}
|
||||
};
|
||||
|
||||
// server start
|
||||
void Socks5Server::start(){
|
||||
this->listenLocal();
|
||||
this->forever();
|
||||
close(this->sockfd);
|
||||
};
|
||||
|
||||
// transfer data form local port to remote server
|
||||
void * thread_fun1(void *val){
|
||||
//pair<int,int> pairval=*((pair<int,int>*)val);
|
||||
int local_sockfd = ((int*)val)[0];
|
||||
int remote_sockfd = ((int*)val)[1];
|
||||
|
||||
// cout << local_sockfd << " ==== " << remote_sockfd << endl;
|
||||
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(local_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from local_sock datalen = " << datalen << endl ;
|
||||
if (datalen<= 0) {
|
||||
// nothing to do
|
||||
break ;
|
||||
}else if(datalen==10){
|
||||
// cout<<"data[10]: "<<data<<endl;
|
||||
string data_len10(data,data+10);
|
||||
if(data_len10=="closesocks"){
|
||||
break;
|
||||
}else{
|
||||
send_len = send(remote_sockfd, data, datalen, 0) ;
|
||||
cout << "send to remote_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}else{ // send to remote server
|
||||
send_len = send(remote_sockfd, data, datalen, 0) ;
|
||||
cout << "send to remote_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// transfer data form remote server to local port
|
||||
void * thread_fun2(void *val){
|
||||
//pair<int,int> pairval=*((pair<int,int>*)val);
|
||||
int local_sockfd = ((int*)val)[0];
|
||||
int remote_sockfd = ((int*)val)[1];
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(remote_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from remote_sock datalen = " << datalen << endl ;
|
||||
if (datalen <= 0) {
|
||||
// 发送一个特殊数据到客户端,提醒其关闭此次连接=>也可以设置心跳包来实现
|
||||
// 由于这里正常情况下传输的是http格式数据,因此这种特殊数据不会跟不同数据混同
|
||||
char closedata[10];
|
||||
string closedata_s="closesocks";
|
||||
strcpy(closedata,closedata_s.c_str());
|
||||
send_len = send(local_sockfd, closedata, 10, 0) ;
|
||||
cout << "send to client_sockfd the 'closesocks', len = " << send_len << endl ;
|
||||
break;
|
||||
}else{
|
||||
// send to localhost
|
||||
send_len = send(local_sockfd, data, datalen, 0) ;
|
||||
cout << "send to local_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#ifndef SOCKS_H_INCLUDED
|
||||
#define SOCKS_H_INCLUDED
|
||||
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define SERV_TCP_PORT 9011 /* Local listening port number */
|
||||
#define MAX_SIZE 1024*7120
|
||||
#define SOCKS5_VERSION 5
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Socks5Server{
|
||||
private:
|
||||
// sockfd
|
||||
int sockfd;
|
||||
// sockaddr
|
||||
struct sockaddr_in serv_addr;
|
||||
/* Local listening port number */
|
||||
int port;
|
||||
// socks version
|
||||
uint8_t socks_vision;
|
||||
// 2 commom numbers
|
||||
uint8_t ui0;
|
||||
uint8_t ui5;
|
||||
|
||||
public:
|
||||
// construction function
|
||||
Socks5Server(){
|
||||
this->port=SERV_TCP_PORT;
|
||||
this->ui0=0;
|
||||
this->ui5=5;
|
||||
this->socks_vision=SOCKS5_VERSION;
|
||||
}
|
||||
Socks5Server(int port){
|
||||
this->port=port;
|
||||
this->ui0=0;
|
||||
this->ui5=5;
|
||||
this->socks_vision=SOCKS5_VERSION;
|
||||
}
|
||||
~Socks5Server(){
|
||||
}
|
||||
// listen to the local port
|
||||
void listenLocal();
|
||||
// waiting for the local port's connection
|
||||
int acceptLocal();
|
||||
// a headshake for the sub-negotiation method
|
||||
int negotShake(int val);
|
||||
// a headshake for the connection information
|
||||
// to remote server
|
||||
pair<int,int> connShake(int val);
|
||||
// data transmission shake
|
||||
void transData(pair<int,int> pairval);
|
||||
// forever listenner function
|
||||
void forever();
|
||||
// server start
|
||||
void start();
|
||||
};
|
||||
|
||||
#endif
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
client: Client.o ClientMain.o
|
||||
g++ -o client ClientMain.o Client.o
|
||||
Client.o : Client.cpp Client.h
|
||||
g++ -c Client.cpp
|
||||
ClientMain.o : ClientMain.cpp
|
||||
g++ -c ClientMain.cpp
|
||||
Binary file not shown.
@@ -0,0 +1,61 @@
|
||||
import logging
|
||||
import select
|
||||
import socket
|
||||
import struct
|
||||
from socketserver import ThreadingMixIn, TCPServer, StreamRequestHandler
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
# SOCKS_VERSION = 5
|
||||
socks_address='127.0.0.1'
|
||||
socks_port=9011
|
||||
|
||||
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
|
||||
pass
|
||||
|
||||
|
||||
class SocksClient(StreamRequestHandler):
|
||||
|
||||
def handle(self):
|
||||
logging.info('Accepting connection from %s:%s' % self.client_address)
|
||||
|
||||
# 建立与socks服务器的连接
|
||||
try:
|
||||
socks_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
socks_server.connect((socks_address, socks_port))
|
||||
logging.info('Connected to %s %s' % (socks_address,socks_port))
|
||||
except Exception as err:
|
||||
logging.error(err)
|
||||
|
||||
# 建立一个本机与代理服务器之间的数据交换连接
|
||||
self.exchange_loop(self.connection, socks_server)
|
||||
|
||||
# 关闭本机数据连接(但继续监听)
|
||||
self.server.close_request(self.request)
|
||||
|
||||
# 作为客户端,交换本机与代理服务器的数据
|
||||
def exchange_loop(self, client, socks_server):
|
||||
count = 0
|
||||
while True:
|
||||
count = count + 1
|
||||
r, w, e = select.select([client, socks_server], [], [])
|
||||
|
||||
# 如果client监听到了来自本机的数据,读取这个数据;
|
||||
# 并让socks_server发送给本机。
|
||||
if client in r:
|
||||
data = client.recv(4096)
|
||||
print("client recv: "+count)
|
||||
if socks_server.send(data) <= 0:
|
||||
break
|
||||
|
||||
# 如果socks_server监听到了来自代理服务器的数据,读取这个数据;
|
||||
# 并让client发送给本机。
|
||||
if socks_server in r:
|
||||
data = socks_server.recv(4096)
|
||||
print("server recv: " + count)
|
||||
if client.send(data) <= 0:
|
||||
break
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 创建一个本机数据监听,端口号为8000
|
||||
with ThreadingTCPServer(('127.0.0.1', 8000), SocksClient) as client:
|
||||
client.serve_forever()
|
||||
Binary file not shown.
@@ -0,0 +1,118 @@
|
||||
import logging
|
||||
import select
|
||||
import socket
|
||||
import struct
|
||||
from socketserver import ThreadingMixIn, TCPServer, StreamRequestHandler
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
SOCKS_VERSION = 5
|
||||
socks_address='127.0.0.1'
|
||||
socks_port=9011
|
||||
|
||||
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
|
||||
pass
|
||||
|
||||
class SocksProxy(StreamRequestHandler):
|
||||
|
||||
def handle(self):
|
||||
logging.info('Accepting connection from %s:%s' % self.client_address)
|
||||
|
||||
# 从客户端获取两个字节的连接代理服务器请求
|
||||
header = self.connection.recv(2) #11111111111111111111111-2
|
||||
# !表示network
|
||||
version, nmethods = struct.unpack("!BB", header)
|
||||
|
||||
# socks 5
|
||||
assert version == SOCKS_VERSION
|
||||
assert nmethods > 0
|
||||
|
||||
# 获取客户端提供的子协商方法
|
||||
methods = self.get_available_methods(nmethods)
|
||||
|
||||
# 如果子协商方法中不存在不需要子协商验证,就关闭此次连接
|
||||
if 0 not in set(methods):
|
||||
self.server.close_request(self.request)
|
||||
return
|
||||
|
||||
# 返回选择的验证方式及socks版本
|
||||
self.connection.sendall(struct.pack("!BB", SOCKS_VERSION, 0))
|
||||
|
||||
# 客户端获得url请求的前几个字节
|
||||
version, cmd, _, address_type = struct.unpack("!BBBB", self.connection.recv(4))
|
||||
assert version == SOCKS_VERSION
|
||||
|
||||
if address_type == 1: # IPv4
|
||||
address = socket.inet_ntoa(self.connection.recv(4))
|
||||
elif address_type == 3: # Domain name
|
||||
domain_length = ord(self.connection.recv(1)[0])
|
||||
address = self.connection.recv(domain_length)
|
||||
|
||||
port = struct.unpack('!H', self.connection.recv(2))[0]
|
||||
|
||||
# 代理服务器对url请求在尝试进行连接之后,向客户端进行连接状态的答复
|
||||
try:
|
||||
if cmd == 1: # CONNECT
|
||||
remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
remote.connect((address, port))
|
||||
bind_address = remote.getsockname()
|
||||
logging.info('Connected to %s %s' % (address, port))
|
||||
else:
|
||||
self.server.close_request(self.request)
|
||||
|
||||
addr = struct.unpack("!I", socket.inet_aton(bind_address[0]))[0]
|
||||
port = bind_address[1]
|
||||
reply = struct.pack("!BBBBIH", SOCKS_VERSION, 0, 0, address_type,
|
||||
addr, port)
|
||||
|
||||
except Exception as err:
|
||||
logging.error(err)
|
||||
reply = self.generate_failed_reply(address_type, 5)
|
||||
|
||||
self.connection.sendall(reply)
|
||||
|
||||
# 建立一个数据交换连接
|
||||
if reply[1] == 0 and cmd == 1:
|
||||
self.exchange_loop(self.connection, remote)
|
||||
|
||||
# 数据交换结束,关闭此次代理请求
|
||||
self.server.close_request(self.request)
|
||||
|
||||
def get_available_methods(self, n):
|
||||
methods = []
|
||||
for i in range(n):
|
||||
methods.append(ord(self.connection.recv(1)))
|
||||
return methods
|
||||
|
||||
# 代理服务器对发生错误的url请求进行
|
||||
def generate_failed_reply(self, address_type, error_number):
|
||||
return struct.pack("!BBBBIH", SOCKS_VERSION, error_number, 0, address_type, 0, 0)
|
||||
|
||||
# 作为代理服务器,交换客户端与远程目的服务器的数据
|
||||
def exchange_loop(self, client, remote):
|
||||
count = 0
|
||||
while True:
|
||||
count = count + 1
|
||||
r, w, e = select.select([client, remote], [], [])
|
||||
|
||||
# 如果client监听到了来自客户端的数据,读取这个数据;
|
||||
# 并让remoto发送这个数据到远程目的服务器。
|
||||
if client in r:
|
||||
data = client.recv(4096)
|
||||
print("client recv: " )
|
||||
if remote.send(data) <= 0:
|
||||
break
|
||||
|
||||
# 如果remote监听到了来自远程目的服务器的数据,读取这个数据;
|
||||
# 并让client发送给客户端。
|
||||
if remote in r:
|
||||
data = remote.recv(4096)
|
||||
print("server recv: " )
|
||||
if client.send(data) <= 0:
|
||||
break
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 创建一个代理服务器监听
|
||||
with ThreadingTCPServer(('127.0.0.1', 9011), SocksProxy) as server:
|
||||
server.serve_forever()
|
||||
|
||||
# curl -v --socks5 127.0.0.1:9011 https://github.com
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,444 @@
|
||||
#include "Socks5Server.h"
|
||||
using namespace std;
|
||||
|
||||
// simulate socks5-server
|
||||
// usage:
|
||||
// 1. "g++ -c Socks5Server.cpp"
|
||||
// 2. "g++ -c main.cpp"
|
||||
// 3. "g++ -o sermax main.o Socks5Server.o -lpthread"
|
||||
// 4. "./sermax"
|
||||
// 5. test:
|
||||
// "curl -v --socks5 127.0.0.1:9011 https://www.baidu.com" => ok
|
||||
// make firefox browser port 9011 => ok
|
||||
// test the ipv6 url:"https://mirrors6.tuna.tsinghua.edu.cn/" => error
|
||||
// 6. Mind: Do not open too many urls, it may make the ipv6 url to kill the program!!!
|
||||
|
||||
// local port listenner thread
|
||||
void* thread_fun1(void *val);
|
||||
// remote server listenner thread
|
||||
void* thread_fun2(void *val);
|
||||
|
||||
// listen to the local port
|
||||
void Socks5Server::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
|
||||
while( bind(this->sockfd, (struct sockaddr *) &(this->serv_addr), sizeof(this->serv_addr)) < 0){
|
||||
sleep(1) ;
|
||||
cout << "bind fail" << endl ;
|
||||
};
|
||||
listen(this->sockfd,10);
|
||||
};
|
||||
|
||||
// waiting for the local port's connection
|
||||
int Socks5Server::acceptLocal(){
|
||||
int newsockfd;
|
||||
struct sockaddr_in cli_addr;
|
||||
int cli_len=sizeof(cli_addr);
|
||||
cout<<"Waitting connection from localhost..."<<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 from localhost"<<endl;
|
||||
|
||||
return newsockfd;
|
||||
};
|
||||
|
||||
// a headshake for the sub-negotiation method
|
||||
int Socks5Server::negotShake(int val){
|
||||
// right flag, the loop is going on when th flag==0
|
||||
int flag=0;
|
||||
// newsockfd
|
||||
int newsockfd = val;
|
||||
//Get 2 bytes of information from the client
|
||||
// - socks version number, total number of negotiation methods
|
||||
char buf1[1];
|
||||
char buf2[2];
|
||||
if (recv(newsockfd, buf2, 2, 0) == -1) {
|
||||
cout<<"cannot get version-nmethod"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
if ((uint8_t)buf2[0] != this->socks_vision) {
|
||||
cout<<"socks version is wrong"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
if ((uint8_t)buf2[1] <= 0) {
|
||||
cout<<"nmethod is wrong"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
cout<<"version-nmethod: ";
|
||||
printf("%x ", buf2[0]);
|
||||
printf("%x \n", buf2[1]);
|
||||
|
||||
//negotiation methods
|
||||
int nmethods = (uint8_t)buf2[1];
|
||||
// the method contains 0 when the m_flag==1
|
||||
int m_flag = 0;
|
||||
for (int i = 0; i < nmethods; i++) {
|
||||
recv(newsockfd, buf1, 1, 0);
|
||||
if ((uint8_t)(buf1[0]) == 0) {
|
||||
m_flag = 1;
|
||||
}
|
||||
cout<<"nmethods: ";
|
||||
printf("%x\n", buf1[0]);
|
||||
}
|
||||
if (m_flag == 0) {
|
||||
cout<<"methods donot have 0"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
//Return request reply (no sub-negotiation required)
|
||||
uint8_t msg2[2];
|
||||
msg2[0] = this->socks_vision;
|
||||
msg2[1] = this->ui0;
|
||||
if (send(newsockfd, msg2, 2, 0) == -1) {
|
||||
cout<<"cannot send socks-methond-reply"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
return flag;
|
||||
};
|
||||
|
||||
// a headshake for the connection information
|
||||
// to remote server
|
||||
pair<int,int> Socks5Server::connShake(int val){
|
||||
// right flag, the loop is going on when th flag==0
|
||||
int flag=0;
|
||||
// newsockfd
|
||||
int newsockfd = val;
|
||||
//Get the first four bytes of information
|
||||
// such as the address type of URL request
|
||||
// from the client
|
||||
char buf4[4];
|
||||
if (recv(newsockfd, buf4, 4, 0) == -1) {
|
||||
cout<<"cannot get version-cmd-_-addressType"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
cout<<"version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
if ((uint8_t)buf4[0] != 5) {
|
||||
cout<<"version is wrong. version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
uint8_t cmd = (uint8_t)buf4[1];
|
||||
if(cmd!=1){
|
||||
cout<<"cmd is not 1"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
uint8_t addressType = (uint8_t)buf4[3];
|
||||
if(addressType!=1){
|
||||
cout<<"address is not ipv4"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
|
||||
//Get the IP address of the destination server of URL request from the client
|
||||
char* r_address;
|
||||
char* domin_address;
|
||||
int remote_addr_length=4;
|
||||
if (addressType == 1) {//ipv4
|
||||
remote_addr_length=4;
|
||||
r_address=new char[4];
|
||||
if (recv(newsockfd, r_address, 4, 0) == -1) {
|
||||
cout<<"cannot get the ipv4\n"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
printf("ipv4: %d %d",(uint8_t)r_address[0],(uint8_t)r_address[1]);
|
||||
printf(" %d %d\n",(uint8_t)r_address[2],(uint8_t)r_address[3]);
|
||||
}else if(addressType==4){//ipv6 => error. killed by me in early code
|
||||
remote_addr_length=16;
|
||||
r_address=new char[16];
|
||||
if (recv(newsockfd, r_address, 16, 0) == -1) {
|
||||
cout<<"cannot get the ipv6\n"<<endl;
|
||||
}
|
||||
printf("ipv6: (...)\n");
|
||||
}else{
|
||||
cout<<"address is not ipv4 or ipv6"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
|
||||
//Listener port of destination server for URL request from client
|
||||
char r_port[2];
|
||||
if (recv(newsockfd, r_port, 2, 0) == -1) {
|
||||
cout<<"cannot get the port\n"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
printf("port: %d %d\n", (uint8_t)r_port[0],(uint8_t)r_port[1]);
|
||||
|
||||
//When the connection to the remote server is successful,
|
||||
// remote server
|
||||
int remote_sockfd;
|
||||
try
|
||||
{
|
||||
if (cmd == 1) {
|
||||
if (addressType == 1){//ipv4
|
||||
//Connect to remote destination server
|
||||
struct sockaddr_in remote_addr;
|
||||
remote_sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
bzero((char *)&remote_addr, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
memcpy(&(remote_addr.sin_addr.s_addr),r_address,remote_addr_length);
|
||||
memcpy(&(remote_addr.sin_port),r_port,2);
|
||||
cout<<"connecting to ipv4..."<<endl;
|
||||
int res_c=connect(remote_sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
if(res_c==-1){
|
||||
cout<<"connect error"<<endl;
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}else{
|
||||
cout<<"connected ipv6"<<endl;
|
||||
printf("Connected to %s:%d\n",inet_ntoa(remote_addr.sin_addr),remote_addr.sin_port);
|
||||
}
|
||||
}else if(addressType == 4){//ipv6 => error
|
||||
//Connect to remote destination server
|
||||
struct sockaddr_in6 remote_addr;
|
||||
remote_sockfd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
bzero((char *)&remote_addr, sizeof(remote_addr));
|
||||
remote_addr.sin6_family = AF_INET6;
|
||||
memcpy(&(remote_addr.sin6_addr.__in6_u.__u6_addr8),r_address,remote_addr_length);
|
||||
memcpy(&(remote_addr.sin6_port),r_port,2);
|
||||
cout<<"connecting to ipv6..."<<endl;
|
||||
int res_c=connect(remote_sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
if(res_c==-1){
|
||||
cout<<"connect error"<<endl;
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}else{
|
||||
cout<<"connected ipv6"<<endl;
|
||||
// printf("Connected to %s:%d\n",remote_addr.sin6_addr.__in6_u.__u6_addr8,remote_addr.sin6_port);
|
||||
}
|
||||
}else{
|
||||
//...
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
printf("cmd is not connection\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
|
||||
//Return connection information to client
|
||||
uint8_t *connRrt;
|
||||
if(addressType==1){//ipv4
|
||||
//getsocketname()
|
||||
sockaddr_in cs_addr;
|
||||
memset(&cs_addr,0,sizeof(cs_addr));
|
||||
int cs_len=sizeof(cs_addr);
|
||||
int res_sn=getsockname(remote_sockfd,(struct sockaddr *)&cs_addr,(socklen_t *)&cs_len);
|
||||
cout<<"Current connection:"<<inet_ntoa(cs_addr.sin_addr)<<":"<<ntohs(cs_addr.sin_port)<<endl;
|
||||
// return info
|
||||
connRrt=new uint8_t[10];
|
||||
connRrt[0]=socks_vision;
|
||||
connRrt[1]=ui0;
|
||||
connRrt[2]=ui0;
|
||||
connRrt[3]=addressType;
|
||||
memcpy(&connRrt[4],&(cs_addr.sin_addr.s_addr),remote_addr_length);
|
||||
memcpy(&connRrt[8],&(cs_addr.sin_port),2);
|
||||
cout<<"the reply ip:"<<endl;
|
||||
for(int i=0;i<4;i++){
|
||||
printf("%d ",(uint8_t)connRrt[4+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
cout<<"the reply port:"<<endl;
|
||||
for(int i=0;i<2;i++){
|
||||
printf("%d ",(uint8_t)connRrt[8+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
if (send(newsockfd, connRrt, 10, 0) == -1) {
|
||||
printf("cannot send url-reply\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
}else if(addressType==4){//ipv6 => error
|
||||
// getsocketname()
|
||||
sockaddr_in6 cs_addr;
|
||||
memset(&cs_addr,0,sizeof(cs_addr));
|
||||
int cs_len=sizeof(cs_addr);
|
||||
int res_sn=getsockname(remote_sockfd,(struct sockaddr *)&cs_addr,(socklen_t *)&cs_len);
|
||||
cout<<"Current connection:"<<"(ipv6...)"<<":"<<ntohs(cs_addr.sin6_port)<<endl;
|
||||
// return info
|
||||
connRrt=new uint8_t[22];
|
||||
connRrt[0]=socks_vision;
|
||||
connRrt[1]=ui0;
|
||||
connRrt[2]=ui0;
|
||||
connRrt[3]=addressType;
|
||||
memcpy(&connRrt[4],&(cs_addr.sin6_addr.__in6_u.__u6_addr8),remote_addr_length);
|
||||
memcpy(&connRrt[20],&(cs_addr.sin6_port),2);
|
||||
cout<<"the reply ip:"<<endl;
|
||||
for(int i=0;i<16;i++){
|
||||
printf("%d ",(uint8_t)connRrt[4+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
cout<<"the reply port:"<<endl;
|
||||
for(int i=0;i<2;i++){
|
||||
printf("%d ",(uint8_t)connRrt[20+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
if (send(newsockfd, connRrt, 22, 0) == -1) {
|
||||
printf("cannot send url-reply\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
}else{}
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
uint8_t err[6];
|
||||
err[0] = socks_vision;
|
||||
err[1] = ui5;
|
||||
err[2] = ui0;
|
||||
err[3] = addressType;
|
||||
err[4] = ui0;
|
||||
err[5] = ui0;
|
||||
if (send(newsockfd, err, 6, 0) == -1) {
|
||||
printf("cannot send url-err-reply\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
}
|
||||
return make_pair(remote_sockfd,flag);
|
||||
|
||||
};
|
||||
|
||||
// data transmission shake
|
||||
void Socks5Server::transData(pair<int,int> pairval){
|
||||
int newsockfd = pairval.first;
|
||||
int remote_sockfd = pairval.second;
|
||||
printf("Data transmission is beginning.\n");
|
||||
// listen to the local port
|
||||
pthread_t tid1 ;
|
||||
|
||||
int sockfds[2] = {newsockfd,remote_sockfd};
|
||||
|
||||
int fpid1;
|
||||
while ( ( fpid1 = fork() ) < 0 ){
|
||||
cout << "create child process 1 failture! Next will retry!" << endl;
|
||||
}
|
||||
if ( 0 == fpid1 ) {
|
||||
cout<<"子进程1 beginning: "<<endl;
|
||||
thread_fun1(sockfds);
|
||||
cout<<"子进程1 exit()"<<endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int fpid2;
|
||||
while ( ( fpid2 = fork() ) < 0 ){
|
||||
cout << "create child process 2 failture! Next will retry!" << endl;
|
||||
}
|
||||
if ( 0 == fpid2 ) {
|
||||
cout<<"子进程2 beginning: "<<endl;
|
||||
thread_fun2(sockfds);
|
||||
cout<<"子进程2 exit()"<<endl;
|
||||
exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
// forever listenner function
|
||||
void Socks5Server::forever(){
|
||||
while(true){
|
||||
int newsockfd = this->acceptLocal();
|
||||
if(this->negotShake(newsockfd)>0){
|
||||
cout<<"negotShake error"<<endl;
|
||||
close(newsockfd);
|
||||
continue;
|
||||
}
|
||||
pair<int,int> pairval=connShake(newsockfd);
|
||||
if(pairval.second>0){
|
||||
cout<<"connShake error"<<endl;
|
||||
close(newsockfd);
|
||||
if(pairval.first>0){
|
||||
close(pairval.first);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int remote_sockfd = pairval.first;
|
||||
this->transData(make_pair(newsockfd,remote_sockfd));
|
||||
}
|
||||
};
|
||||
|
||||
// server start
|
||||
void Socks5Server::start(){
|
||||
this->listenLocal();
|
||||
this->forever();
|
||||
close(this->sockfd);
|
||||
};
|
||||
|
||||
// transfer data form local port to remote server
|
||||
void * thread_fun1(void *val){
|
||||
//pair<int,int> pairval=*((pair<int,int>*)val);
|
||||
int local_sockfd = ((int*)val)[0];
|
||||
int remote_sockfd = ((int*)val)[1];
|
||||
|
||||
// cout << local_sockfd << " ==== " << remote_sockfd << endl;
|
||||
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(local_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from local_sock datalen = " << datalen << endl ;
|
||||
if (datalen<= 0) {
|
||||
|
||||
break ;
|
||||
}else{ // send to remote server
|
||||
send_len = send(remote_sockfd, data, datalen, 0) ;
|
||||
cout << "send to remote_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// transfer data form remote server to local port
|
||||
void * thread_fun2(void *val){
|
||||
//pair<int,int> pairval=*((pair<int,int>*)val);
|
||||
int local_sockfd = ((int*)val)[0];
|
||||
int remote_sockfd = ((int*)val)[1];
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(remote_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from remote_sock datalen = " << datalen << endl ;
|
||||
if (datalen <= 0) {
|
||||
//nothing
|
||||
break;
|
||||
}else{
|
||||
// send to localhost
|
||||
send_len = send(local_sockfd, data, datalen, 0) ;
|
||||
cout << "send to local_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifndef SOCKS_H_INCLUDED
|
||||
#define SOCKS_H_INCLUDED
|
||||
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sys/time.h>
|
||||
// #include <pthread.h>
|
||||
|
||||
#define SERV_TCP_PORT 9011 /* Local listening port number */
|
||||
#define MAX_SIZE 1024*7120
|
||||
#define SOCKS5_VERSION 5
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Socks5Server{
|
||||
public:
|
||||
// sockfd
|
||||
int sockfd;
|
||||
// sockaddr
|
||||
struct sockaddr_in serv_addr;
|
||||
/* Local listening port number */
|
||||
int port;
|
||||
// socks version
|
||||
uint8_t socks_vision;
|
||||
// 2 commom numbers
|
||||
uint8_t ui0;
|
||||
uint8_t ui5;
|
||||
|
||||
public:
|
||||
// construction function
|
||||
Socks5Server(){
|
||||
this->port=SERV_TCP_PORT;
|
||||
this->ui0=0;
|
||||
this->ui5=5;
|
||||
this->socks_vision=SOCKS5_VERSION;
|
||||
}
|
||||
Socks5Server(int port){
|
||||
this->port=port;
|
||||
this->ui0=0;
|
||||
this->ui5=5;
|
||||
this->socks_vision=SOCKS5_VERSION;
|
||||
}
|
||||
~Socks5Server(){
|
||||
}
|
||||
// listen to the local port
|
||||
void listenLocal();
|
||||
// waiting for the local port's connection
|
||||
int acceptLocal();
|
||||
// a headshake for the sub-negotiation method
|
||||
int negotShake(int val);
|
||||
// a headshake for the connection information
|
||||
// to remote server
|
||||
pair<int,int> connShake(int val);
|
||||
// data transmission shake
|
||||
void transData(pair<int,int> pairval);
|
||||
// forever listenner function
|
||||
void forever();
|
||||
// server start
|
||||
void start();
|
||||
};
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
||||
#include "Socks5Server.h"
|
||||
// #include "Socks5Server.cpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(){
|
||||
// new a server
|
||||
Socks5Server *ss_server=new Socks5Server();
|
||||
|
||||
// server start
|
||||
ss_server->start();
|
||||
|
||||
// delete
|
||||
delete ss_server;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,457 @@
|
||||
#include "Socks5Server.h"
|
||||
using namespace std;
|
||||
|
||||
// simulate socks5-server
|
||||
// usage:
|
||||
// 1. "g++ -c Socks5Server.cpp"
|
||||
// 2. "g++ -c main.cpp"
|
||||
// 3. "g++ -o sermax main.o Socks5Server.o -lpthread"
|
||||
// 4. "./sermax"
|
||||
// 5. test:
|
||||
// "curl -v --socks5 127.0.0.1:9011 https://www.baidu.com" => ok
|
||||
// make firefox browser port 9011 => ok
|
||||
// test the ipv6 url:"https://mirrors6.tuna.tsinghua.edu.cn/" => error
|
||||
// 6. Mind: Do not open too many urls, it may make the ipv6 url to kill the program!!!
|
||||
|
||||
// local port listenner thread
|
||||
void* thread_fun1(void *val);
|
||||
// remote server listenner thread
|
||||
void* thread_fun2(void *val);
|
||||
|
||||
// listen to the local port
|
||||
void Socks5Server::listenLocal(){
|
||||
this->sockfd=socket(AF_INET, SOCK_STREAM, 0);
|
||||
// do following thing so that we can bind our port again
|
||||
// int opt = 1;
|
||||
// int len = sizeof(opt);
|
||||
// while(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, (socklen_t)len)<0){
|
||||
// cout<<"set sockopt error"<<endl;
|
||||
// };
|
||||
/* 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
|
||||
while( bind(this->sockfd, (struct sockaddr *) &(this->serv_addr), sizeof(this->serv_addr)) < 0){
|
||||
sleep(1) ;
|
||||
cout << "bind fail" << endl ;
|
||||
};
|
||||
listen(this->sockfd,10);
|
||||
};
|
||||
|
||||
// waiting for the local port's connection
|
||||
int Socks5Server::acceptLocal(){
|
||||
int newsockfd;
|
||||
struct sockaddr_in cli_addr;
|
||||
int cli_len=sizeof(cli_addr);
|
||||
cout<<"Waitting connection from localhost..."<<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 from localhost"<<endl;
|
||||
|
||||
return newsockfd;
|
||||
};
|
||||
|
||||
// a headshake for the sub-negotiation method
|
||||
int Socks5Server::negotShake(int val){
|
||||
// right flag, the loop is going on when th flag==0
|
||||
int flag=0;
|
||||
// newsockfd
|
||||
int newsockfd = val;
|
||||
//Get 2 bytes of information from the client
|
||||
// - socks version number, total number of negotiation methods
|
||||
char buf1[1];
|
||||
char buf2[2];
|
||||
if (recv(newsockfd, buf2, 2, 0) == -1) {
|
||||
cout<<"cannot get version-nmethod"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
if ((uint8_t)buf2[0] != this->socks_vision) {
|
||||
cout<<"socks version is wrong"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
if ((uint8_t)buf2[1] <= 0) {
|
||||
cout<<"nmethod is wrong"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
cout<<"version-nmethod: ";
|
||||
printf("%x ", buf2[0]);
|
||||
printf("%x \n", buf2[1]);
|
||||
|
||||
//negotiation methods
|
||||
int nmethods = (uint8_t)buf2[1];
|
||||
// the method contains 0 when the m_flag==1
|
||||
int m_flag = 0;
|
||||
for (int i = 0; i < nmethods; i++) {
|
||||
recv(newsockfd, buf1, 1, 0);
|
||||
if ((uint8_t)(buf1[0]) == 0) {
|
||||
m_flag = 1;
|
||||
}
|
||||
cout<<"nmethods: ";
|
||||
printf("%x\n", buf1[0]);
|
||||
}
|
||||
if (m_flag == 0) {
|
||||
cout<<"methods donot have 0"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
//Return request reply (no sub-negotiation required)
|
||||
uint8_t msg2[2];
|
||||
msg2[0] = this->socks_vision;
|
||||
msg2[1] = this->ui0;
|
||||
if (send(newsockfd, msg2, 2, 0) == -1) {
|
||||
cout<<"cannot send socks-methond-reply"<<endl;
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
return flag;
|
||||
};
|
||||
|
||||
// a headshake for the connection information
|
||||
// to remote server
|
||||
pair<int,int> Socks5Server::connShake(int val){
|
||||
// right flag, the loop is going on when th flag==0
|
||||
int flag=0;
|
||||
// newsockfd
|
||||
int newsockfd = val;
|
||||
//Get the first four bytes of information
|
||||
// such as the address type of URL request
|
||||
// from the client
|
||||
char buf4[4];
|
||||
if (recv(newsockfd, buf4, 4, 0) == -1) {
|
||||
cout<<"cannot get version-cmd-_-addressType"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
cout<<"version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
if ((uint8_t)buf4[0] != 5) {
|
||||
cout<<"version is wrong. version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
uint8_t cmd = (uint8_t)buf4[1];
|
||||
if(cmd!=1){
|
||||
cout<<"cmd is not 1"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
uint8_t addressType = (uint8_t)buf4[3];
|
||||
if(addressType!=1){
|
||||
cout<<"address is not ipv4"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
|
||||
//Get the IP address of the destination server of URL request from the client
|
||||
char* r_address;
|
||||
char* domin_address;
|
||||
int remote_addr_length=4;
|
||||
if (addressType == 1) {//ipv4
|
||||
remote_addr_length=4;
|
||||
r_address=new char[4];
|
||||
if (recv(newsockfd, r_address, 4, 0) == -1) {
|
||||
cout<<"cannot get the ipv4\n"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
printf("ipv4: %d %d",(uint8_t)r_address[0],(uint8_t)r_address[1]);
|
||||
printf(" %d %d\n",(uint8_t)r_address[2],(uint8_t)r_address[3]);
|
||||
}else if(addressType==4){//ipv6 => error. killed by me in early code
|
||||
remote_addr_length=16;
|
||||
r_address=new char[16];
|
||||
if (recv(newsockfd, r_address, 16, 0) == -1) {
|
||||
cout<<"cannot get the ipv6\n"<<endl;
|
||||
}
|
||||
printf("ipv6: (...)\n");
|
||||
}else{
|
||||
cout<<"address is not ipv4 or ipv6"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
|
||||
//Listener port of destination server for URL request from client
|
||||
char r_port[2];
|
||||
if (recv(newsockfd, r_port, 2, 0) == -1) {
|
||||
cout<<"cannot get the port\n"<<endl;
|
||||
flag=1;
|
||||
return make_pair(-1,flag);
|
||||
}
|
||||
printf("port: %d %d\n", (uint8_t)r_port[0],(uint8_t)r_port[1]);
|
||||
|
||||
//When the connection to the remote server is successful,
|
||||
// remote server
|
||||
int remote_sockfd;
|
||||
try
|
||||
{
|
||||
if (cmd == 1) {
|
||||
if (addressType == 1){//ipv4
|
||||
//Connect to remote destination server
|
||||
struct sockaddr_in remote_addr;
|
||||
remote_sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
bzero((char *)&remote_addr, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
memcpy(&(remote_addr.sin_addr.s_addr),r_address,remote_addr_length);
|
||||
memcpy(&(remote_addr.sin_port),r_port,2);
|
||||
cout<<"connecting to ipv4..."<<endl;
|
||||
int res_c=connect(remote_sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
if(res_c==-1){
|
||||
cout<<"connect error"<<endl;
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}else{
|
||||
cout<<"connected ipv6"<<endl;
|
||||
printf("Connected to %s:%d\n",inet_ntoa(remote_addr.sin_addr),remote_addr.sin_port);
|
||||
}
|
||||
}else if(addressType == 4){//ipv6 => error
|
||||
//Connect to remote destination server
|
||||
struct sockaddr_in6 remote_addr;
|
||||
remote_sockfd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
bzero((char *)&remote_addr, sizeof(remote_addr));
|
||||
remote_addr.sin6_family = AF_INET6;
|
||||
memcpy(&(remote_addr.sin6_addr.__in6_u.__u6_addr8),r_address,remote_addr_length);
|
||||
memcpy(&(remote_addr.sin6_port),r_port,2);
|
||||
cout<<"connecting to ipv6..."<<endl;
|
||||
int res_c=connect(remote_sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
if(res_c==-1){
|
||||
cout<<"connect error"<<endl;
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}else{
|
||||
cout<<"connected ipv6"<<endl;
|
||||
// printf("Connected to %s:%d\n",remote_addr.sin6_addr.__in6_u.__u6_addr8,remote_addr.sin6_port);
|
||||
}
|
||||
}else{
|
||||
//...
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
printf("cmd is not connection\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
|
||||
//Return connection information to client
|
||||
uint8_t *connRrt;
|
||||
if(addressType==1){//ipv4
|
||||
//getsocketname()
|
||||
sockaddr_in cs_addr;
|
||||
memset(&cs_addr,0,sizeof(cs_addr));
|
||||
int cs_len=sizeof(cs_addr);
|
||||
int res_sn=getsockname(remote_sockfd,(struct sockaddr *)&cs_addr,(socklen_t *)&cs_len);
|
||||
cout<<"Current connection:"<<inet_ntoa(cs_addr.sin_addr)<<":"<<ntohs(cs_addr.sin_port)<<endl;
|
||||
// return info
|
||||
connRrt=new uint8_t[10];
|
||||
connRrt[0]=socks_vision;
|
||||
connRrt[1]=ui0;
|
||||
connRrt[2]=ui0;
|
||||
connRrt[3]=addressType;
|
||||
memcpy(&connRrt[4],&(cs_addr.sin_addr.s_addr),remote_addr_length);
|
||||
memcpy(&connRrt[8],&(cs_addr.sin_port),2);
|
||||
cout<<"the reply ip:"<<endl;
|
||||
for(int i=0;i<4;i++){
|
||||
printf("%d ",(uint8_t)connRrt[4+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
cout<<"the reply port:"<<endl;
|
||||
for(int i=0;i<2;i++){
|
||||
printf("%d ",(uint8_t)connRrt[8+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
if (send(newsockfd, connRrt, 10, 0) == -1) {
|
||||
printf("cannot send url-reply\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
}else if(addressType==4){//ipv6 => error
|
||||
// getsocketname()
|
||||
sockaddr_in6 cs_addr;
|
||||
memset(&cs_addr,0,sizeof(cs_addr));
|
||||
int cs_len=sizeof(cs_addr);
|
||||
int res_sn=getsockname(remote_sockfd,(struct sockaddr *)&cs_addr,(socklen_t *)&cs_len);
|
||||
cout<<"Current connection:"<<"(ipv6...)"<<":"<<ntohs(cs_addr.sin6_port)<<endl;
|
||||
// return info
|
||||
connRrt=new uint8_t[22];
|
||||
connRrt[0]=socks_vision;
|
||||
connRrt[1]=ui0;
|
||||
connRrt[2]=ui0;
|
||||
connRrt[3]=addressType;
|
||||
memcpy(&connRrt[4],&(cs_addr.sin6_addr.__in6_u.__u6_addr8),remote_addr_length);
|
||||
memcpy(&connRrt[20],&(cs_addr.sin6_port),2);
|
||||
cout<<"the reply ip:"<<endl;
|
||||
for(int i=0;i<16;i++){
|
||||
printf("%d ",(uint8_t)connRrt[4+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
cout<<"the reply port:"<<endl;
|
||||
for(int i=0;i<2;i++){
|
||||
printf("%d ",(uint8_t)connRrt[20+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
if (send(newsockfd, connRrt, 22, 0) == -1) {
|
||||
printf("cannot send url-reply\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
}else{}
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
uint8_t err[6];
|
||||
err[0] = socks_vision;
|
||||
err[1] = ui5;
|
||||
err[2] = ui0;
|
||||
err[3] = addressType;
|
||||
err[4] = ui0;
|
||||
err[5] = ui0;
|
||||
if (send(newsockfd, err, 6, 0) == -1) {
|
||||
printf("cannot send url-err-reply\n");
|
||||
flag=1;
|
||||
return make_pair(remote_sockfd,flag);
|
||||
}
|
||||
}
|
||||
return make_pair(remote_sockfd,flag);
|
||||
|
||||
};
|
||||
|
||||
// data transmission shake
|
||||
void Socks5Server::transData(pair<int,int> pairval){
|
||||
int newsockfd = pairval.first;
|
||||
int remote_sockfd = pairval.second;
|
||||
printf("Data transmission is beginning.\n");
|
||||
|
||||
int sockfds[2] = {newsockfd,remote_sockfd};
|
||||
|
||||
pid_t fpid1;
|
||||
while ( ( fpid1 = fork() ) < 0 ){
|
||||
cout << "create child process 1 failture! Next will retry!" << endl;
|
||||
}
|
||||
if ( 0 == fpid1 ) {
|
||||
cout<<"子进程1 beginning: "<<endl;
|
||||
thread_fun1(sockfds);
|
||||
cout<<"子进程1 exit()"<<endl;
|
||||
// close the fd in the son process
|
||||
close(this->sockfd);
|
||||
// exit the son process
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pid_t fpid2;
|
||||
while ( ( fpid2 = fork() ) < 0 ){
|
||||
cout << "create child process 2 failture! Next will retry!" << endl;
|
||||
}
|
||||
if ( 0 == fpid2 ) {
|
||||
cout<<"子进程2 beginning: "<<endl;
|
||||
thread_fun2(sockfds);
|
||||
cout<<"子进程2 exit()"<<endl;
|
||||
// close the fd in the son process
|
||||
close(this->sockfd);
|
||||
// exit the son process
|
||||
exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
// forever listenner function
|
||||
void Socks5Server::forever(){
|
||||
while(true){
|
||||
int newsockfd = this->acceptLocal();
|
||||
if(this->negotShake(newsockfd)>0){
|
||||
cout<<"negotShake error"<<endl;
|
||||
close(newsockfd);
|
||||
continue;
|
||||
}
|
||||
pair<int,int> pairval=connShake(newsockfd);
|
||||
if(pairval.second>0){
|
||||
cout<<"connShake error"<<endl;
|
||||
close(newsockfd);
|
||||
if(pairval.first>0){
|
||||
close(pairval.first);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int remote_sockfd = pairval.first;
|
||||
this->transData(make_pair(newsockfd,remote_sockfd));
|
||||
// close the fds in main process
|
||||
close(newsockfd);
|
||||
close(remote_sockfd);
|
||||
}
|
||||
};
|
||||
|
||||
// server start
|
||||
void Socks5Server::start(){
|
||||
this->listenLocal();
|
||||
this->forever();
|
||||
close(this->sockfd);
|
||||
};
|
||||
|
||||
// transfer data form local port to remote server
|
||||
void * thread_fun1(void *val){
|
||||
//pair<int,int> pairval=*((pair<int,int>*)val);
|
||||
int local_sockfd = ((int*)val)[0];
|
||||
int remote_sockfd = ((int*)val)[1];
|
||||
|
||||
// cout << local_sockfd << " ==== " << remote_sockfd << endl;
|
||||
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(local_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from local_sock datalen = " << datalen << endl ;
|
||||
if (datalen<= 0) {
|
||||
|
||||
break ;
|
||||
}else{ // send to remote server
|
||||
send_len = send(remote_sockfd, data, datalen, 0) ;
|
||||
cout << "send to remote_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// transfer data form remote server to local port
|
||||
void * thread_fun2(void *val){
|
||||
//pair<int,int> pairval=*((pair<int,int>*)val);
|
||||
int local_sockfd = ((int*)val)[0];
|
||||
int remote_sockfd = ((int*)val)[1];
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(remote_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from remote_sock datalen = " << datalen << endl ;
|
||||
if (datalen <= 0) {
|
||||
//nothing
|
||||
break;
|
||||
}else{
|
||||
// send to localhost
|
||||
send_len = send(local_sockfd, data, datalen, 0) ;
|
||||
cout << "send to local_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifndef SOCKS_H_INCLUDED
|
||||
#define SOCKS_H_INCLUDED
|
||||
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sys/time.h>
|
||||
// #include <pthread.h>
|
||||
|
||||
#define SERV_TCP_PORT 9011 /* Local listening port number */
|
||||
#define MAX_SIZE 1024*7120
|
||||
#define SOCKS5_VERSION 5
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Socks5Server{
|
||||
public:
|
||||
// sockfd
|
||||
int sockfd;
|
||||
// sockaddr
|
||||
struct sockaddr_in serv_addr;
|
||||
/* Local listening port number */
|
||||
int port;
|
||||
// socks version
|
||||
uint8_t socks_vision;
|
||||
// 2 commom numbers
|
||||
uint8_t ui0;
|
||||
uint8_t ui5;
|
||||
|
||||
public:
|
||||
// construction function
|
||||
Socks5Server(){
|
||||
this->port=SERV_TCP_PORT;
|
||||
this->ui0=0;
|
||||
this->ui5=5;
|
||||
this->socks_vision=SOCKS5_VERSION;
|
||||
}
|
||||
Socks5Server(int port){
|
||||
this->port=port;
|
||||
this->ui0=0;
|
||||
this->ui5=5;
|
||||
this->socks_vision=SOCKS5_VERSION;
|
||||
}
|
||||
~Socks5Server(){
|
||||
}
|
||||
// listen to the local port
|
||||
void listenLocal();
|
||||
// waiting for the local port's connection
|
||||
int acceptLocal();
|
||||
// a headshake for the sub-negotiation method
|
||||
int negotShake(int val);
|
||||
// a headshake for the connection information
|
||||
// to remote server
|
||||
pair<int,int> connShake(int val);
|
||||
// data transmission shake
|
||||
void transData(pair<int,int> pairval);
|
||||
// forever listenner function
|
||||
void forever();
|
||||
// server start
|
||||
void start();
|
||||
};
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
||||
#include "Socks5Server.h"
|
||||
// #include "Socks5Server.cpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(){
|
||||
// new a server
|
||||
Socks5Server *ss_server=new Socks5Server();
|
||||
|
||||
// server start
|
||||
ss_server->start();
|
||||
|
||||
// delete
|
||||
delete ss_server;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,374 @@
|
||||
#include "Socks5Server.h"
|
||||
using namespace std;
|
||||
|
||||
// simulate socks5-server
|
||||
// usage:
|
||||
// 1. "g++ -c Socks5Server.cpp"
|
||||
// 2. "g++ -c main.cpp"
|
||||
// 3. "g++ -o sermax main.o Socks5Server.o -lpthread"
|
||||
// 4. "./sermax"
|
||||
// 5. test:
|
||||
// "curl -v --socks5 127.0.0.1:9011 https://www.baidu.com" => ok
|
||||
// make firefox browser's port 9011 => ok
|
||||
|
||||
// local port listenner thread
|
||||
void* thread_fun1(void* val);
|
||||
// remote server listenner thread
|
||||
void* thread_fun2(void* val);
|
||||
|
||||
// listen to the local port
|
||||
void Socks5Server::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
|
||||
while( bind(this->sockfd, (struct sockaddr *) &(this->serv_addr), sizeof(this->serv_addr)) < 0){
|
||||
sleep(1) ;
|
||||
cout << "bind fail" << endl ;
|
||||
};
|
||||
listen(this->sockfd,10);
|
||||
};
|
||||
|
||||
// waiting for the local port's connection
|
||||
int Socks5Server::acceptLocal(){
|
||||
int newsockfd;
|
||||
struct sockaddr_in cli_addr;
|
||||
int cli_len=sizeof(cli_addr);
|
||||
cout<<"Waitting connection from localhost..."<<endl;
|
||||
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&cli_len);
|
||||
if (newsockfd < 0) {
|
||||
cout<<"can't bind local address"<<endl;
|
||||
}else{
|
||||
cout<<"Acceptted a connection from localhost"<<endl;
|
||||
}
|
||||
return newsockfd;
|
||||
};
|
||||
|
||||
// a headshake for the sub-negotiation method
|
||||
int Socks5Server::negotShake(int val){
|
||||
// right flag, the loop is going on when th flag==0
|
||||
int flag=0;
|
||||
// newsockfd
|
||||
int newsockfd = val;
|
||||
//Get 2 bytes of information from the client
|
||||
// - socks version number, total number of negotiation methods
|
||||
char buf1[1];
|
||||
char buf2[2];
|
||||
if (recv(newsockfd, buf2, 2, 0) == -1) {
|
||||
cout<<"cannot get version-nmethod"<<endl;
|
||||
}
|
||||
if ((uint8_t)buf2[0] != this->socks_vision) {
|
||||
cout<<"socks version is wrong"<<endl;
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
if ((uint8_t)buf2[1] <= 0) {
|
||||
cout<<"nmethod is wrong"<<endl;
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
cout<<"version-nmethod: ";
|
||||
printf("%x ", buf2[0]);
|
||||
printf("%x \n", buf2[1]);
|
||||
|
||||
//negotiation methods
|
||||
int nmethods = (uint8_t)buf2[1];
|
||||
// the method contains 0 when the m_flag==1
|
||||
int m_flag = 0;
|
||||
for (int i = 0; i < nmethods; i++) {
|
||||
recv(newsockfd, buf1, 1, 0);
|
||||
if ((uint8_t)(buf1[0]) == 0) {
|
||||
m_flag = 1;
|
||||
}
|
||||
cout<<"nmethods: ";
|
||||
printf("%x\n", buf1[0]);
|
||||
}
|
||||
if (m_flag == 0) {
|
||||
cout<<"methods donot have 0"<<endl;
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
return flag;
|
||||
}
|
||||
|
||||
//Return request reply (no sub-negotiation required)
|
||||
uint8_t msg2[2];
|
||||
msg2[0] = this->socks_vision;
|
||||
msg2[1] = this->ui0;
|
||||
if (send(newsockfd, msg2, 2, 0) == -1) {
|
||||
cout<<"cannot send socks-methond-reply"<<endl;
|
||||
}
|
||||
|
||||
return flag;
|
||||
};
|
||||
|
||||
// a headshake for the connection information
|
||||
// to remote server
|
||||
pair<int,int> Socks5Server::connShake(int val){
|
||||
// right flag, the loop is going on when th flag==0
|
||||
int flag=0;
|
||||
// newsockfd
|
||||
int newsockfd = val;
|
||||
//Get the first four bytes of information
|
||||
// such as the address type of URL request
|
||||
// from the client
|
||||
char buf4[4];
|
||||
if (recv(newsockfd, buf4, 4, 0) == -1) {
|
||||
cout<<"cannot get version-cmd-_-addressType"<<endl;
|
||||
}
|
||||
cout<<"version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
if ((uint8_t)buf4[0] != 5) {
|
||||
cout<<"version is wrong. version-cmd-_-addressType: ";
|
||||
printf("%x ", buf4[0]);
|
||||
printf("%x ", buf4[1]);
|
||||
printf("%x \n", buf4[3]);
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
return make_pair(1,1);
|
||||
}
|
||||
uint8_t cmd = (uint8_t)buf4[1];
|
||||
if(cmd!=1){
|
||||
cout<<"cmd is not 1"<<endl;
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
return make_pair(1,1);
|
||||
}
|
||||
uint8_t addressType = (uint8_t)buf4[3];
|
||||
|
||||
//Get the IP address of the destination server of URL request from the client
|
||||
char* r_address;
|
||||
char* domin_address;
|
||||
int remote_addr_length=4;
|
||||
if (addressType == 1) {//ipv4
|
||||
r_address=new char[4];
|
||||
if (recv(newsockfd, r_address, 4, 0) == -1) {
|
||||
cout<<"cannot get the ipv4\n"<<endl;
|
||||
}
|
||||
printf("ipv4: %d %d",(uint8_t)r_address[0],(uint8_t)r_address[1]);
|
||||
printf(" %d %d\n",(uint8_t)r_address[2],(uint8_t)r_address[3]);
|
||||
}else{
|
||||
cout<<"address is not ipv4"<<endl;
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
return make_pair(1,1);
|
||||
}
|
||||
|
||||
//Listener port of destination server for URL request from client
|
||||
char r_port[2];
|
||||
if (recv(newsockfd, r_port, 2, 0) == -1) {
|
||||
cout<<"cannot get the port\n"<<endl;
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
return make_pair(1,1);
|
||||
}
|
||||
printf("port: %d %d\n", (uint8_t)r_port[0],(uint8_t)r_port[1]);
|
||||
|
||||
//When the connection to the remote server is successful,
|
||||
// remote server
|
||||
int remote_sockfd;
|
||||
struct sockaddr_in remote_addr;
|
||||
try
|
||||
{
|
||||
if (cmd == 1) {
|
||||
//Connect to remote destination server
|
||||
remote_sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
bzero((char *)&remote_addr, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
if ((addressType == 1)||(addressType==4)){
|
||||
memcpy(&(remote_addr.sin_addr.s_addr),r_address,remote_addr_length);
|
||||
}else if(addressType == 3){
|
||||
memcpy(&(remote_addr.sin_addr.s_addr),domin_address,remote_addr_length);
|
||||
}
|
||||
memcpy(&(remote_addr.sin_port),r_port,2);
|
||||
|
||||
cout<<"connecting..."<<endl;
|
||||
int res_c=connect(remote_sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
if(res_c==-1){
|
||||
cout<<"connect error"<<endl;
|
||||
close(newsockfd);
|
||||
close(remote_sockfd);
|
||||
flag=1;
|
||||
}
|
||||
cout<<"connected"<<endl;
|
||||
|
||||
//Print Successful Connection Tips
|
||||
if (addressType == 1){
|
||||
printf("Connected to %s:%d\n",inet_ntoa(remote_addr.sin_addr),remote_addr.sin_port);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
printf("cmd is not connection\n");
|
||||
close(newsockfd);
|
||||
flag=1;
|
||||
}
|
||||
|
||||
//getsocketname()
|
||||
sockaddr_in cs_addr;
|
||||
memset(&cs_addr,0,sizeof(cs_addr));
|
||||
int cs_len=sizeof(cs_addr);
|
||||
int res_sn=getsockname(remote_sockfd,(struct sockaddr *)&cs_addr,(socklen_t *)&cs_len);
|
||||
cout<<"Current connection Socket IP:"<<inet_ntoa(cs_addr.sin_addr)<<":"<<ntohs(cs_addr.sin_port)<<endl;
|
||||
|
||||
//Return connection information to client
|
||||
uint8_t *connRrt;
|
||||
if(addressType==1){
|
||||
connRrt=new uint8_t[10];
|
||||
connRrt[0]=socks_vision;
|
||||
connRrt[1]=ui0;
|
||||
connRrt[2]=ui0;
|
||||
connRrt[3]=addressType;
|
||||
memcpy(&connRrt[4],&(cs_addr.sin_addr.s_addr),4);
|
||||
memcpy(&connRrt[8],&(cs_addr.sin_port),2);
|
||||
cout<<"the reply ip:"<<endl;
|
||||
for(int i=0;i<4;i++){
|
||||
printf("%d ",(uint8_t)connRrt[4+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
cout<<"the reply port:"<<endl;
|
||||
for(int i=0;i<2;i++){
|
||||
printf("%d ",(uint8_t)connRrt[8+i]);
|
||||
}
|
||||
cout<<endl;
|
||||
}else{}
|
||||
|
||||
if (send(newsockfd, connRrt, 10, 0) == -1) {
|
||||
printf("cannot send url-reply\n");
|
||||
flag=1;
|
||||
}
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
uint8_t err[6];
|
||||
err[0] = socks_vision;
|
||||
err[1] = ui5;
|
||||
err[2] = ui0;
|
||||
err[3] = addressType;
|
||||
err[4] = ui0;
|
||||
err[5] = ui0;
|
||||
if (send(newsockfd, err, 6, 0) == -1) {
|
||||
printf("cannot send url-err-reply\n");
|
||||
flag=1;
|
||||
}
|
||||
}
|
||||
return make_pair(remote_sockfd,flag);
|
||||
|
||||
};
|
||||
|
||||
// data transmission shake
|
||||
void Socks5Server::transData(pair<int,int> pairval){
|
||||
int newsockfd = pairval.first;
|
||||
int remote_sockfd = pairval.second;
|
||||
printf("Data transmission is beginning.\n");
|
||||
struct mypara
|
||||
{
|
||||
int para1;//参数1
|
||||
int para2;//参数2
|
||||
};
|
||||
struct mypara pstru={newsockfd,remote_sockfd};
|
||||
|
||||
// listen to the local port
|
||||
pthread_t tid1 ;
|
||||
int ret1 = pthread_create(&tid1,NULL,thread_fun1,&(pstru));
|
||||
cout<<"thread return1: "<<ret1<<endl;
|
||||
// listen to the remote server
|
||||
pthread_t tid2 ;
|
||||
int ret2 = pthread_create(&tid2,NULL,thread_fun2,&(pstru));
|
||||
cout<<"thread return2: "<<ret2<<endl;
|
||||
|
||||
};
|
||||
|
||||
// forever listenner function
|
||||
void Socks5Server::forever(){
|
||||
while(true){
|
||||
int newsockfd = this->acceptLocal();
|
||||
if(this->negotShake(newsockfd)>0){
|
||||
cout<<"negotShake error"<<endl;
|
||||
continue;
|
||||
}
|
||||
pair<int,int> pairval=connShake(newsockfd);
|
||||
if(pairval.second>0){
|
||||
cout<<"connShake error"<<endl;
|
||||
continue;
|
||||
}
|
||||
int remote_sockfd = pairval.first;
|
||||
this->transData(make_pair(newsockfd,remote_sockfd));
|
||||
}
|
||||
};
|
||||
|
||||
// server start
|
||||
void Socks5Server::start(){
|
||||
this->listenLocal();
|
||||
this->forever();
|
||||
close(this->sockfd);
|
||||
};
|
||||
|
||||
// transfer data form local port to remote server
|
||||
void * thread_fun1(void* val){
|
||||
struct mypara
|
||||
{
|
||||
int para1;//参数1
|
||||
int para2;//参数2
|
||||
};
|
||||
mypara *pstru;
|
||||
pstru = (struct mypara *) val;
|
||||
// pair<int,int> pairval=*((pair<int,int>*)val);
|
||||
int local_sockfd = pstru->para1;
|
||||
int remote_sockfd= pstru->para2;
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(local_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from local_sock datalen = " << datalen << endl ;
|
||||
if (datalen<= 0) {
|
||||
break ;
|
||||
}else{ // send to remote server
|
||||
send_len = send(remote_sockfd, data, datalen, 0) ;
|
||||
cout << "send to remote_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// transfer data form remote server to local port
|
||||
void * thread_fun2(void* val){
|
||||
struct mypara
|
||||
{
|
||||
int para1;//参数1
|
||||
int para2;//参数2
|
||||
};
|
||||
mypara *pstru;
|
||||
pstru = (struct mypara *) val;
|
||||
// pair<int,int> pairval=*((pair<int,int>*)val);
|
||||
int local_sockfd = pstru->para1;
|
||||
int remote_sockfd= pstru->para2;
|
||||
char data[MAX_SIZE];
|
||||
int datalen;
|
||||
int send_len = 0 ;
|
||||
while(true){
|
||||
datalen=recv(remote_sockfd, data, sizeof(data), 0);
|
||||
cout << "recv from remote_sock datalen = " << datalen << endl ;
|
||||
if (datalen <= 0) {
|
||||
//nothing
|
||||
break;
|
||||
}else{
|
||||
// send to localhost
|
||||
send_len = send(local_sockfd, data, datalen, 0) ;
|
||||
cout << "send to local_sockfd len = " << send_len << endl ;
|
||||
}
|
||||
}
|
||||
close(local_sockfd) ;
|
||||
close(remote_sockfd) ;
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#ifndef SOCKS_H_INCLUDED
|
||||
#define SOCKS_H_INCLUDED
|
||||
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#define SERV_TCP_PORT 9011 /* Local listening port number */
|
||||
#define MAX_SIZE 1024*5120
|
||||
#define SOCKS5_VERSION 5
|
||||
#define THREAD_NUMBER 10
|
||||
using namespace std;
|
||||
|
||||
class Socks5Server{
|
||||
public:
|
||||
// sockfd
|
||||
int sockfd;
|
||||
// sockaddr
|
||||
struct sockaddr_in serv_addr;
|
||||
/* Local listening port number */
|
||||
int port;
|
||||
// socks version
|
||||
uint8_t socks_vision;
|
||||
// 2 commom numbers
|
||||
uint8_t ui0;
|
||||
uint8_t ui5;
|
||||
|
||||
public:
|
||||
// construction function
|
||||
Socks5Server(){
|
||||
this->port=SERV_TCP_PORT;
|
||||
this->ui0=0;
|
||||
this->ui5=5;
|
||||
this->socks_vision=SOCKS5_VERSION;
|
||||
}
|
||||
Socks5Server(int port){
|
||||
this->port=port;
|
||||
this->ui0=0;
|
||||
this->ui5=5;
|
||||
this->socks_vision=SOCKS5_VERSION;
|
||||
}
|
||||
~Socks5Server(){
|
||||
}
|
||||
// listen to the local port
|
||||
void listenLocal();
|
||||
// waiting for the local port's connection
|
||||
int acceptLocal();
|
||||
// a headshake for the sub-negotiation method
|
||||
int negotShake(int val);
|
||||
// a headshake for the connection information
|
||||
// to remote server
|
||||
pair<int,int> connShake(int val);
|
||||
// data transmission shake
|
||||
void transData(pair<int,int> pairval);
|
||||
// forever listenner function
|
||||
void forever();
|
||||
// server start
|
||||
void start();
|
||||
};
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
#include "Socks5Server.h"
|
||||
using namespace std;
|
||||
int main(){
|
||||
// new a server
|
||||
Socks5Server *ss_server=new Socks5Server();
|
||||
// server start
|
||||
ss_server->start();
|
||||
// delete
|
||||
delete ss_server;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user