commit 774e4254f106dbbe34db3da1a780cc83649eee6b Author: my-style <2647778488@qq.com> Date: Sun Feb 23 20:44:48 2020 +0800 socks5_demo及http_vpn项目 diff --git a/http_vpn_20191209/README.md b/http_vpn_20191209/README.md new file mode 100644 index 0000000..13dcc2a --- /dev/null +++ b/http_vpn_20191209/README.md @@ -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中的丢包问题的解决(需要进行丢包测试方法的设计); diff --git a/http_vpn_20191209/ccn_p2p/PriorQueuePool/PriorQueue.cpp b/http_vpn_20191209/ccn_p2p/PriorQueuePool/PriorQueue.cpp new file mode 100644 index 0000000..62ded2e --- /dev/null +++ b/http_vpn_20191209/ccn_p2p/PriorQueuePool/PriorQueue.cpp @@ -0,0 +1,177 @@ +#include +#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): "<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: "<headSeq; + // cout<<"pos: "<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: "<dataPriorQueue[pos]=ds; + count++; + // cout<<"success set"<countmaxNum) { +// pthread_cond_wait(&full_cond , &mutex) ; +// } +// pthread_mutex_unlock(&mutex) ; +// }; + +// 判断该队列是否放满了数据 +bool PriorQueue::isfull(){ + return this->count==this->getMaxNum(); +} + +// 返回完整数据包 +char* PriorQueue::getDataPacket(){ + // cout<<"*********getDataPacket Information********"<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): "<dataTail!=0){ + clen=this->dataTail; + } + memcpy(&dp[rear],dataPriorQueue[i].data,clen); + rear+=dataTail; + // 释放数据区内存 + vector vtemp; + this->dataPriorQueue.swap(vtemp); + // cout<<"sizeof(datapq): "< +#include +#include +#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 dataPriorQueue; + // vector dataPriorQueue; + // 数据锁: + // 对可能在线程之间读写冲突的共享数据进行加锁。 + // pthread_cond_t full_cond ; //条件锁 + // pthread_mutex_t mutex ; //互斥锁 + + private: + int parseData(const char* dataSeg,int len,char* rawdata); +}; + +#endif \ No newline at end of file diff --git a/http_vpn_20191209/ccn_p2p/PriorQueuePool/PriorQueue.o b/http_vpn_20191209/ccn_p2p/PriorQueuePool/PriorQueue.o new file mode 100644 index 0000000..921820b Binary files /dev/null and b/http_vpn_20191209/ccn_p2p/PriorQueuePool/PriorQueue.o differ diff --git a/http_vpn_20191209/ccn_p2p/PriorQueuePool/QueuePool.cpp b/http_vpn_20191209/ccn_p2p/PriorQueuePool/QueuePool.cpp new file mode 100644 index 0000000..c95e2f8 --- /dev/null +++ b/http_vpn_20191209/ccn_p2p/PriorQueuePool/QueuePool.cpp @@ -0,0 +1,169 @@ +#include +#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."<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."<::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::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"<::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<getWantSeq()<printRQueue(); + // 头部等待队列 + cout<<"--------------------------------------------------------------------"<flag_head==0){ + cout<<"the head queue of the first level queue is null."<headQueue.getHeadSeq() + <::iterator it; + cout<<"Their headSeq(s) are: "; + for(it=waitQueues.begin();it!=waitQueues.end();it++){ + cout<<(*it).first<<" "; + } + cout< +#include +#include +#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 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 \ No newline at end of file diff --git a/http_vpn_20191209/ccn_p2p/PriorQueuePool/QueuePool.o b/http_vpn_20191209/ccn_p2p/PriorQueuePool/QueuePool.o new file mode 100644 index 0000000..99c3c2d Binary files /dev/null and b/http_vpn_20191209/ccn_p2p/PriorQueuePool/QueuePool.o differ diff --git a/http_vpn_20191209/ccn_p2p/PriorQueuePool/makefile b/http_vpn_20191209/ccn_p2p/PriorQueuePool/makefile new file mode 100644 index 0000000..fca563e --- /dev/null +++ b/http_vpn_20191209/ccn_p2p/PriorQueuePool/makefile @@ -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 \ No newline at end of file diff --git a/http_vpn_20191209/ccn_p2p/PriorQueuePool/r_queue.cpp b/http_vpn_20191209/ccn_p2p/PriorQueuePool/r_queue.cpp new file mode 100644 index 0000000..be872ad --- /dev/null +++ b/http_vpn_20191209/ccn_p2p/PriorQueuePool/r_queue.cpp @@ -0,0 +1,164 @@ +#include +#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) ; +} diff --git a/http_vpn_20191209/ccn_p2p/PriorQueuePool/r_queue.h b/http_vpn_20191209/ccn_p2p/PriorQueuePool/r_queue.h new file mode 100644 index 0000000..4ca81b3 --- /dev/null +++ b/http_vpn_20191209/ccn_p2p/PriorQueuePool/r_queue.h @@ -0,0 +1,60 @@ +#ifndef _R_QUEUE_H_ +#define _R_QUEUE_H_ +// 针对数据包已按照发送顺序缓存得到的数据队列 +#include +#include +#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 diff --git a/http_vpn_20191209/ccn_p2p/PriorQueuePool/r_queue.o b/http_vpn_20191209/ccn_p2p/PriorQueuePool/r_queue.o new file mode 100644 index 0000000..8d6a146 Binary files /dev/null and b/http_vpn_20191209/ccn_p2p/PriorQueuePool/r_queue.o differ diff --git a/http_vpn_20191209/ccn_p2p/PriorQueuePool/testMain.cpp b/http_vpn_20191209/ccn_p2p/PriorQueuePool/testMain.cpp new file mode 100644 index 0000000..2a3b44f --- /dev/null +++ b/http_vpn_20191209/ccn_p2p/PriorQueuePool/testMain.cpp @@ -0,0 +1,157 @@ +#include +#include +#include +#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<pushDataSegment(resultData4,15+HEAD_LEN); + + cout<pushDataSegment(resultData2,14+HEAD_LEN); + + cout<pushDataSegment(resultData0,15+HEAD_LEN); + + cout<pushDataSegment(resultData3,15+HEAD_LEN); + + cout<pushDataSegment(resultData5,13+HEAD_LEN); + + cout<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<setDataSegment(resultData2,8012); + +// cout<setDataSegment(resultData1,8012); + +// cout<setDataSegment(resultData3,7012); + +// char *dataPacket; + +// cout<getDataPacket(); + +// cout<setDataSegment(resultData2,15+HEAD_LEN); + +// cout<setDataSegment(resultData1,15+HEAD_LEN); + +// cout<setDataSegment(resultData3,14+HEAD_LEN); + +// // 组装数据包区 +// char *dataPacket; + +// cout<getDataPacket(); + +// cout< +#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): "<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: "<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(resultData), c_len+HEAD_LEN) ; + // data_pkt.setContent(reinterpret_cast(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: "<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 : " <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: "<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.getContent().value()), + // data_sz) ; + qp.pushDataSegment(reinterpret_cast(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(); +} + diff --git a/http_vpn_20191209/ccn_p2p/ndn_socket.h b/http_vpn_20191209/ccn_p2p/ndn_socket.h new file mode 100644 index 0000000..d3aa145 --- /dev/null +++ b/http_vpn_20191209/ccn_p2p/ndn_socket.h @@ -0,0 +1,86 @@ +#ifndef _NDN_SOCKET_H_ +#define _NDN_SOCKET_H_ +// 功能 : 启动一个face,并往固定的前缀发送数据 +#include +#include +#include +#include +#include +#include +#include "PriorQueuePool/QueuePool.h" +#include +#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 + diff --git a/http_vpn_20191209/ccn_p2p/ndn_socket.o b/http_vpn_20191209/ccn_p2p/ndn_socket.o new file mode 100644 index 0000000..7dcdc0d Binary files /dev/null and b/http_vpn_20191209/ccn_p2p/ndn_socket.o differ diff --git a/http_vpn_20191209/ccn_p2p/ndnp2p_recv.h b/http_vpn_20191209/ccn_p2p/ndnp2p_recv.h new file mode 100644 index 0000000..91916b3 --- /dev/null +++ b/http_vpn_20191209/ccn_p2p/ndnp2p_recv.h @@ -0,0 +1,4 @@ +#ifndef _NDNP2P_RECV_H_ +#define _NDNP2P_RECV_H_ + +#endif diff --git a/http_vpn_20191209/ccn_p2p/ndnp2p_recv1.cpp b/http_vpn_20191209/ccn_p2p/ndnp2p_recv1.cpp new file mode 100644 index 0000000..85beeda --- /dev/null +++ b/http_vpn_20191209/ccn_p2p/ndnp2p_recv1.cpp @@ -0,0 +1,28 @@ +#include +#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 0){ + cout << "count = " << ++recv_count << endl ; + cout<<"recv buff: "; + for(int x=0;xsockfd=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] ..."<sockfd, (struct sockaddr *) &cli_addr, + (socklen_t *)&cli_len); + // error + while(newsockfd<0){ + cout<<"can't accept from local address"<sockfd); + this->listenLocal(); + newsockfd = accept(this->sockfd, (struct sockaddr *) &cli_addr, + (socklen_t *)&cli_len); + } + cout<<"Acceptted a connection [client]"<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: "<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; +} \ No newline at end of file diff --git a/http_vpn_20191209/client/Client.h b/http_vpn_20191209/client/Client.h new file mode 100644 index 0000000..0a5d90e --- /dev/null +++ b/http_vpn_20191209/client/Client.h @@ -0,0 +1,92 @@ +#ifndef SOCKS_H_INCLUDED +#define SOCKS_H_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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: "<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: "<start(); + delete client; +} \ No newline at end of file diff --git a/http_vpn_20191209/client/ClientMain.h b/http_vpn_20191209/client/ClientMain.h new file mode 100644 index 0000000..e69de29 diff --git a/http_vpn_20191209/client/ClientMain.o b/http_vpn_20191209/client/ClientMain.o new file mode 100644 index 0000000..b442d24 Binary files /dev/null and b/http_vpn_20191209/client/ClientMain.o differ diff --git a/http_vpn_20191209/client/client b/http_vpn_20191209/client/client new file mode 100644 index 0000000..630d9de Binary files /dev/null and b/http_vpn_20191209/client/client differ diff --git a/http_vpn_20191209/client/makefile b/http_vpn_20191209/client/makefile new file mode 100644 index 0000000..c9f3d0e --- /dev/null +++ b/http_vpn_20191209/client/makefile @@ -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) diff --git a/http_vpn_20191209/server/ServerMain.cpp b/http_vpn_20191209/server/ServerMain.cpp new file mode 100644 index 0000000..6f2c073 --- /dev/null +++ b/http_vpn_20191209/server/ServerMain.cpp @@ -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; +} \ No newline at end of file diff --git a/http_vpn_20191209/server/ServerMain.h b/http_vpn_20191209/server/ServerMain.h new file mode 100644 index 0000000..e69de29 diff --git a/http_vpn_20191209/server/ServerMain.o b/http_vpn_20191209/server/ServerMain.o new file mode 100644 index 0000000..ab5bb1f Binary files /dev/null and b/http_vpn_20191209/server/ServerMain.o differ diff --git a/http_vpn_20191209/server/Socks5Server.cpp b/http_vpn_20191209/server/Socks5Server.cpp new file mode 100644 index 0000000..7bd598d --- /dev/null +++ b/http_vpn_20191209/server/Socks5Server.cpp @@ -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] ..."<socks_vision) { + cout<<"socks version is wrong"<socks_vision; + msg2[1] = this->ui0; + if (ndn_socket.write(msg2,2) < 0) { + cout<<"cannot send socks-methond-reply"< 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"<ndn_negotShake(ndn_socket)>0){ + cout<<"negotShake error"< pairval= ndn_connShake(ndn_socket) ; + if(pairval.second>0){ + cout<<"connShake error"<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()"<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; +} diff --git a/http_vpn_20191209/server/Socks5Server.h b/http_vpn_20191209/server/Socks5Server.h new file mode 100644 index 0000000..0358887 --- /dev/null +++ b/http_vpn_20191209/server/Socks5Server.h @@ -0,0 +1,89 @@ +#ifndef SOCKS_H_INCLUDED +#define SOCKS_H_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 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 diff --git a/http_vpn_20191209/server/Socks5Server.o b/http_vpn_20191209/server/Socks5Server.o new file mode 100644 index 0000000..ed22768 Binary files /dev/null and b/http_vpn_20191209/server/Socks5Server.o differ diff --git a/http_vpn_20191209/server/makefile b/http_vpn_20191209/server/makefile new file mode 100644 index 0000000..cee7600 --- /dev/null +++ b/http_vpn_20191209/server/makefile @@ -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) diff --git a/http_vpn_20191209/server/server b/http_vpn_20191209/server/server new file mode 100644 index 0000000..175e4b0 Binary files /dev/null and b/http_vpn_20191209/server/server differ diff --git a/socks5_demo_201909/.vs/ProjectSettings.json b/socks5_demo_201909/.vs/ProjectSettings.json new file mode 100644 index 0000000..51b37fe --- /dev/null +++ b/socks5_demo_201909/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": "无配置" +} \ No newline at end of file diff --git a/socks5_demo_201909/.vs/VSWorkspaceState.json b/socks5_demo_201909/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..a7c2505 --- /dev/null +++ b/socks5_demo_201909/.vs/VSWorkspaceState.json @@ -0,0 +1,7 @@ +{ + "ExpandedNodes": [ + "" + ], + "SelectedNode": "\\server.cpp", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/socks5_demo_201909/.vs/slnx.sqlite b/socks5_demo_201909/.vs/slnx.sqlite new file mode 100644 index 0000000..e87e59f Binary files /dev/null and b/socks5_demo_201909/.vs/slnx.sqlite differ diff --git a/socks5_demo_201909/.vs/socks5_Demo_pkusz/v15/.suo b/socks5_demo_201909/.vs/socks5_Demo_pkusz/v15/.suo new file mode 100644 index 0000000..1d45cd6 Binary files /dev/null and b/socks5_demo_201909/.vs/socks5_Demo_pkusz/v15/.suo differ diff --git a/socks5_demo_201909/.vs/socks5_Demo_pkusz/v15/Browse.VC.db b/socks5_demo_201909/.vs/socks5_Demo_pkusz/v15/Browse.VC.db new file mode 100644 index 0000000..56022f9 Binary files /dev/null and b/socks5_demo_201909/.vs/socks5_Demo_pkusz/v15/Browse.VC.db differ diff --git a/socks5_demo_201909/.vs/socks5_Demo_pkusz/v15/ipch/AutoPCH/90fdb6538f747cdb/SERVER.ipch b/socks5_demo_201909/.vs/socks5_Demo_pkusz/v15/ipch/AutoPCH/90fdb6538f747cdb/SERVER.ipch new file mode 100644 index 0000000..667ee72 Binary files /dev/null and b/socks5_demo_201909/.vs/socks5_Demo_pkusz/v15/ipch/AutoPCH/90fdb6538f747cdb/SERVER.ipch differ diff --git a/socks5_demo_201909/C++版_v1/server_thread.cpp b/socks5_demo_201909/C++版_v1/server_thread.cpp new file mode 100644 index 0000000..556e0f9 --- /dev/null +++ b/socks5_demo_201909/C++版_v1/server_thread.cpp @@ -0,0 +1,337 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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"< 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..."<socks_vision) { + cout<<"socks version is wrong"<socks_vision; + msg2[1] = this->ui0; + if (send(newsockfd, msg2, 2, 0) == -1) { + cout<<"cannot send socks-methond-reply"< 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"< 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: "<acceptLocal(); + if(this->negotShake(newsockfd)>0){ + cout<<"negotShake error"< pairval=connShake(newsockfd); + if(pairval.second>0){ + cout<<"connShake error"<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 pairval=*((pair*)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 pairval=*((pair*)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; +} diff --git a/socks5_demo_201909/C++版_v2/Socks5Server.h b/socks5_demo_201909/C++版_v2/Socks5Server.h new file mode 100644 index 0000000..ed6f0ed --- /dev/null +++ b/socks5_demo_201909/C++版_v2/Socks5Server.h @@ -0,0 +1,68 @@ +#ifndef SOCKS_H_INCLUDED +#define SOCKS_H_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 connShake(int val); + // data transmission shake + void transData(pair pairval); + // forever listenner function + void forever(); + // server start + void start(); +}; + +#endif diff --git a/socks5_demo_201909/C++版_v2/Socks5Server.o b/socks5_demo_201909/C++版_v2/Socks5Server.o new file mode 100644 index 0000000..08ce778 Binary files /dev/null and b/socks5_demo_201909/C++版_v2/Socks5Server.o differ diff --git a/socks5_demo_201909/C++版_v2/main.cpp b/socks5_demo_201909/C++版_v2/main.cpp new file mode 100644 index 0000000..16d2e6c --- /dev/null +++ b/socks5_demo_201909/C++版_v2/main.cpp @@ -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; +} \ No newline at end of file diff --git a/socks5_demo_201909/C++版_v2/main.o b/socks5_demo_201909/C++版_v2/main.o new file mode 100644 index 0000000..839b034 Binary files /dev/null and b/socks5_demo_201909/C++版_v2/main.o differ diff --git a/socks5_demo_201909/C++版_v2/sermax b/socks5_demo_201909/C++版_v2/sermax new file mode 100644 index 0000000..8dae837 Binary files /dev/null and b/socks5_demo_201909/C++版_v2/sermax differ diff --git a/socks5_demo_201909/C++版_v3.zip b/socks5_demo_201909/C++版_v3.zip new file mode 100644 index 0000000..ecd02bd Binary files /dev/null and b/socks5_demo_201909/C++版_v3.zip differ diff --git a/socks5_demo_201909/C++版_v3/Socks5Server.cpp b/socks5_demo_201909/C++版_v3/Socks5Server.cpp new file mode 100644 index 0000000..71900f9 --- /dev/null +++ b/socks5_demo_201909/C++版_v3/Socks5Server.cpp @@ -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"<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..."<sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&cli_len); + // error + while(newsockfd<0){ + cout<<"can't accept from local address"<sockfd); + this->listenLocal(); + newsockfd = accept(this->sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&cli_len); + } + cout<<"Acceptted a connection from localhost"<socks_vision) { + cout<<"socks version is wrong"<socks_vision; + msg2[1] = this->ui0; + if (send(newsockfd, msg2, 2, 0) == -1) { + cout<<"cannot send socks-methond-reply"< 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"< 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"< 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..."< 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...)"<<":"< 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: "<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: "<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"< pairval=connShake(newsockfd); + if(pairval.second>0){ + cout<<"connShake error"<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 pairval=*((pair*)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 pairval=*((pair*)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; +} diff --git a/socks5_demo_201909/C++版_v3/Socks5Server.h b/socks5_demo_201909/C++版_v3/Socks5Server.h new file mode 100644 index 0000000..7939fe7 --- /dev/null +++ b/socks5_demo_201909/C++版_v3/Socks5Server.h @@ -0,0 +1,70 @@ +#ifndef SOCKS_H_INCLUDED +#define SOCKS_H_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include + +#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 connShake(int val); + // data transmission shake + void transData(pair pairval); + // forever listenner function + void forever(); + // server start + void start(); +}; + +#endif diff --git a/socks5_demo_201909/C++版_v3/Socks5Server.o b/socks5_demo_201909/C++版_v3/Socks5Server.o new file mode 100644 index 0000000..718ec8b Binary files /dev/null and b/socks5_demo_201909/C++版_v3/Socks5Server.o differ diff --git a/socks5_demo_201909/C++版_v3/main.cpp b/socks5_demo_201909/C++版_v3/main.cpp new file mode 100644 index 0000000..89df156 --- /dev/null +++ b/socks5_demo_201909/C++版_v3/main.cpp @@ -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; +} diff --git a/socks5_demo_201909/C++版_v3/main.o b/socks5_demo_201909/C++版_v3/main.o new file mode 100644 index 0000000..839b034 Binary files /dev/null and b/socks5_demo_201909/C++版_v3/main.o differ diff --git a/socks5_demo_201909/C++版_v3/s b/socks5_demo_201909/C++版_v3/s new file mode 100644 index 0000000..f56f864 Binary files /dev/null and b/socks5_demo_201909/C++版_v3/s differ diff --git a/socks5_demo_201909/C++版_v4.zip b/socks5_demo_201909/C++版_v4.zip new file mode 100644 index 0000000..e2fb9c6 Binary files /dev/null and b/socks5_demo_201909/C++版_v4.zip differ diff --git a/socks5_demo_201909/C++版_v4/Client.cpp b/socks5_demo_201909/C++版_v4/Client.cpp new file mode 100644 index 0000000..15e55cd --- /dev/null +++ b/socks5_demo_201909/C++版_v4/Client.cpp @@ -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] ..."<sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&cli_len); + // error + while(newsockfd<0){ + cout<<"can't accept from local address"<sockfd); + this->listenLocal(); + newsockfd = accept(this->sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&cli_len); + } + cout<<"Acceptted a connection [client]"< 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: "<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: "<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..."<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 pairval=*((pair*)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 pairval=*((pair*)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]: "<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 pairval); + // forever listenner function + void forever(); + // server start + void start(); +}; + +#endif \ No newline at end of file diff --git a/socks5_demo_201909/C++版_v4/Client.o b/socks5_demo_201909/C++版_v4/Client.o new file mode 100644 index 0000000..66c71fe Binary files /dev/null and b/socks5_demo_201909/C++版_v4/Client.o differ diff --git a/socks5_demo_201909/C++版_v4/ClientMain.cpp b/socks5_demo_201909/C++版_v4/ClientMain.cpp new file mode 100644 index 0000000..0ab14e7 --- /dev/null +++ b/socks5_demo_201909/C++版_v4/ClientMain.cpp @@ -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 \ No newline at end of file diff --git a/socks5_demo_201909/C++版_v4/ClientMain.o b/socks5_demo_201909/C++版_v4/ClientMain.o new file mode 100644 index 0000000..252ca06 Binary files /dev/null and b/socks5_demo_201909/C++版_v4/ClientMain.o differ diff --git a/socks5_demo_201909/C++版_v4/ServerMain.cpp b/socks5_demo_201909/C++版_v4/ServerMain.cpp new file mode 100644 index 0000000..86a5af2 --- /dev/null +++ b/socks5_demo_201909/C++版_v4/ServerMain.cpp @@ -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 diff --git a/socks5_demo_201909/C++版_v4/ServerMain.o b/socks5_demo_201909/C++版_v4/ServerMain.o new file mode 100644 index 0000000..da05457 Binary files /dev/null and b/socks5_demo_201909/C++版_v4/ServerMain.o differ diff --git a/socks5_demo_201909/C++版_v4/Socks5Server.cpp b/socks5_demo_201909/C++版_v4/Socks5Server.cpp new file mode 100644 index 0000000..572a4d9 --- /dev/null +++ b/socks5_demo_201909/C++版_v4/Socks5Server.cpp @@ -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] ..."<sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&cli_len); + // error + while(newsockfd<0){ + cout<<"can't accept from local address"<sockfd); + this->listenLocal(); + newsockfd = accept(this->sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&cli_len); + } + cout<<"Acceptted a connection [socks5 server]"<socks_vision) { + cout<<"socks version is wrong"<socks_vision; + msg2[1] = this->ui0; + if (send(newsockfd, msg2, 2, 0) == -1) { + cout<<"cannot send socks-methond-reply"< 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"< 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: "<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: "<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"< pairval=connShake(newsockfd); + if(pairval.second>0){ + cout<<"connShake error"<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 pairval=*((pair*)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]: "< 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 diff --git a/socks5_demo_201909/other/20190817.mkv b/socks5_demo_201909/other/20190817.mkv new file mode 100644 index 0000000..33764cc Binary files /dev/null and b/socks5_demo_201909/other/20190817.mkv differ diff --git a/socks5_demo_201909/other/20190817_2.mkv b/socks5_demo_201909/other/20190817_2.mkv new file mode 100644 index 0000000..6d30920 Binary files /dev/null and b/socks5_demo_201909/other/20190817_2.mkv differ diff --git a/socks5_demo_201909/other/20190817_4.mkv b/socks5_demo_201909/other/20190817_4.mkv new file mode 100644 index 0000000..872ddb9 Binary files /dev/null and b/socks5_demo_201909/other/20190817_4.mkv differ diff --git a/socks5_demo_201909/other/20190817_5.mkv b/socks5_demo_201909/other/20190817_5.mkv new file mode 100644 index 0000000..4a36876 Binary files /dev/null and b/socks5_demo_201909/other/20190817_5.mkv differ diff --git a/socks5_demo_201909/other/C++版_v3.01_20190817.zip b/socks5_demo_201909/other/C++版_v3.01_20190817.zip new file mode 100644 index 0000000..bbd2009 Binary files /dev/null and b/socks5_demo_201909/other/C++版_v3.01_20190817.zip differ diff --git a/socks5_demo_201909/other/C++版_v3.01_20190817/20190817.mkv b/socks5_demo_201909/other/C++版_v3.01_20190817/20190817.mkv new file mode 100644 index 0000000..4a36876 Binary files /dev/null and b/socks5_demo_201909/other/C++版_v3.01_20190817/20190817.mkv differ diff --git a/socks5_demo_201909/other/C++版_v3.01_20190817/Socks5Server.cpp b/socks5_demo_201909/other/C++版_v3.01_20190817/Socks5Server.cpp new file mode 100644 index 0000000..0c4cdb5 --- /dev/null +++ b/socks5_demo_201909/other/C++版_v3.01_20190817/Socks5Server.cpp @@ -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..."<sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&cli_len); + // error + while(newsockfd<0){ + cout<<"can't accept from local address"<sockfd); + this->listenLocal(); + newsockfd = accept(this->sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&cli_len); + } + cout<<"Acceptted a connection from localhost"<socks_vision) { + cout<<"socks version is wrong"<socks_vision; + msg2[1] = this->ui0; + if (send(newsockfd, msg2, 2, 0) == -1) { + cout<<"cannot send socks-methond-reply"< 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"< 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"< 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..."< 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...)"<<":"< 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: "<acceptLocal(); + if(this->negotShake(newsockfd)>0){ + cout<<"negotShake error"< pairval=connShake(newsockfd); + if(pairval.second>0){ + cout<<"connShake error"<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 pairval=*((pair*)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 pairval=*((pair*)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; +} diff --git a/socks5_demo_201909/other/C++版_v3.01_20190817/Socks5Server.h b/socks5_demo_201909/other/C++版_v3.01_20190817/Socks5Server.h new file mode 100644 index 0000000..7939fe7 --- /dev/null +++ b/socks5_demo_201909/other/C++版_v3.01_20190817/Socks5Server.h @@ -0,0 +1,70 @@ +#ifndef SOCKS_H_INCLUDED +#define SOCKS_H_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include + +#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 connShake(int val); + // data transmission shake + void transData(pair pairval); + // forever listenner function + void forever(); + // server start + void start(); +}; + +#endif diff --git a/socks5_demo_201909/other/C++版_v3.01_20190817/Socks5Server.o b/socks5_demo_201909/other/C++版_v3.01_20190817/Socks5Server.o new file mode 100644 index 0000000..d63415a Binary files /dev/null and b/socks5_demo_201909/other/C++版_v3.01_20190817/Socks5Server.o differ diff --git a/socks5_demo_201909/other/C++版_v3.01_20190817/main.cpp b/socks5_demo_201909/other/C++版_v3.01_20190817/main.cpp new file mode 100644 index 0000000..89df156 --- /dev/null +++ b/socks5_demo_201909/other/C++版_v3.01_20190817/main.cpp @@ -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; +} diff --git a/socks5_demo_201909/other/C++版_v3.01_20190817/main.o b/socks5_demo_201909/other/C++版_v3.01_20190817/main.o new file mode 100644 index 0000000..839b034 Binary files /dev/null and b/socks5_demo_201909/other/C++版_v3.01_20190817/main.o differ diff --git a/socks5_demo_201909/other/C++版_v3.01_20190817/s b/socks5_demo_201909/other/C++版_v3.01_20190817/s new file mode 100644 index 0000000..67c669f Binary files /dev/null and b/socks5_demo_201909/other/C++版_v3.01_20190817/s differ diff --git a/socks5_demo_201909/other/C++版_v3.02_20190818.zip b/socks5_demo_201909/other/C++版_v3.02_20190818.zip new file mode 100644 index 0000000..4eeeee1 Binary files /dev/null and b/socks5_demo_201909/other/C++版_v3.02_20190818.zip differ diff --git a/socks5_demo_201909/other/C++版_v3.02_20190818/Socks5Server.cpp b/socks5_demo_201909/other/C++版_v3.02_20190818/Socks5Server.cpp new file mode 100644 index 0000000..4edfccc --- /dev/null +++ b/socks5_demo_201909/other/C++版_v3.02_20190818/Socks5Server.cpp @@ -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"<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..."<sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&cli_len); + // error + while(newsockfd<0){ + cout<<"can't accept from local address"<sockfd); + this->listenLocal(); + newsockfd = accept(this->sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&cli_len); + } + cout<<"Acceptted a connection from localhost"<socks_vision) { + cout<<"socks version is wrong"<socks_vision; + msg2[1] = this->ui0; + if (send(newsockfd, msg2, 2, 0) == -1) { + cout<<"cannot send socks-methond-reply"< 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"< 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"< 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..."< 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...)"<<":"< 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: "<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: "<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"< pairval=connShake(newsockfd); + if(pairval.second>0){ + cout<<"connShake error"<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 pairval=*((pair*)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 pairval=*((pair*)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; +} diff --git a/socks5_demo_201909/other/C++版_v3.02_20190818/Socks5Server.h b/socks5_demo_201909/other/C++版_v3.02_20190818/Socks5Server.h new file mode 100644 index 0000000..7939fe7 --- /dev/null +++ b/socks5_demo_201909/other/C++版_v3.02_20190818/Socks5Server.h @@ -0,0 +1,70 @@ +#ifndef SOCKS_H_INCLUDED +#define SOCKS_H_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include + +#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 connShake(int val); + // data transmission shake + void transData(pair pairval); + // forever listenner function + void forever(); + // server start + void start(); +}; + +#endif diff --git a/socks5_demo_201909/other/C++版_v3.02_20190818/Socks5Server.o b/socks5_demo_201909/other/C++版_v3.02_20190818/Socks5Server.o new file mode 100644 index 0000000..718ec8b Binary files /dev/null and b/socks5_demo_201909/other/C++版_v3.02_20190818/Socks5Server.o differ diff --git a/socks5_demo_201909/other/C++版_v3.02_20190818/main.cpp b/socks5_demo_201909/other/C++版_v3.02_20190818/main.cpp new file mode 100644 index 0000000..89df156 --- /dev/null +++ b/socks5_demo_201909/other/C++版_v3.02_20190818/main.cpp @@ -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; +} diff --git a/socks5_demo_201909/other/C++版_v3.02_20190818/main.o b/socks5_demo_201909/other/C++版_v3.02_20190818/main.o new file mode 100644 index 0000000..839b034 Binary files /dev/null and b/socks5_demo_201909/other/C++版_v3.02_20190818/main.o differ diff --git a/socks5_demo_201909/other/C++版_v3.02_20190818/s b/socks5_demo_201909/other/C++版_v3.02_20190818/s new file mode 100644 index 0000000..f56f864 Binary files /dev/null and b/socks5_demo_201909/other/C++版_v3.02_20190818/s differ diff --git a/socks5_demo_201909/other/Socks5Server.cpp b/socks5_demo_201909/other/Socks5Server.cpp new file mode 100644 index 0000000..3616b21 --- /dev/null +++ b/socks5_demo_201909/other/Socks5Server.cpp @@ -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..."<socks_vision) { + cout<<"socks version is wrong"<socks_vision; + msg2[1] = this->ui0; + if (send(newsockfd, msg2, 2, 0) == -1) { + cout<<"cannot send socks-methond-reply"< 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"< 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: "<acceptLocal(); + if(this->negotShake(newsockfd)>0){ + cout<<"negotShake error"< pairval=connShake(newsockfd); + if(pairval.second>0){ + cout<<"connShake error"<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 pairval=*((pair*)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 pairval=*((pair*)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; +} diff --git a/socks5_demo_201909/other/Socks5Server.h b/socks5_demo_201909/other/Socks5Server.h new file mode 100644 index 0000000..55d33cd --- /dev/null +++ b/socks5_demo_201909/other/Socks5Server.h @@ -0,0 +1,69 @@ +#ifndef SOCKS_H_INCLUDED +#define SOCKS_H_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 connShake(int val); + // data transmission shake + void transData(pair pairval); + // forever listenner function + void forever(); + // server start + void start(); +}; + +#endif diff --git a/socks5_demo_201909/other/Socks5Server.o b/socks5_demo_201909/other/Socks5Server.o new file mode 100644 index 0000000..1315040 Binary files /dev/null and b/socks5_demo_201909/other/Socks5Server.o differ diff --git a/socks5_demo_201909/other/main.cpp b/socks5_demo_201909/other/main.cpp new file mode 100644 index 0000000..16d2e6c --- /dev/null +++ b/socks5_demo_201909/other/main.cpp @@ -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; +} \ No newline at end of file diff --git a/socks5_demo_201909/other/main.o b/socks5_demo_201909/other/main.o new file mode 100644 index 0000000..839b034 Binary files /dev/null and b/socks5_demo_201909/other/main.o differ diff --git a/socks5_demo_201909/other/sermax b/socks5_demo_201909/other/sermax new file mode 100644 index 0000000..29cc0e1 Binary files /dev/null and b/socks5_demo_201909/other/sermax differ diff --git a/socks5_demo_201909/other/server b/socks5_demo_201909/other/server new file mode 100644 index 0000000..c7f499b Binary files /dev/null and b/socks5_demo_201909/other/server differ diff --git a/socks5_demo_201909/other/server.cpp b/socks5_demo_201909/other/server.cpp new file mode 100644 index 0000000..528a18b --- /dev/null +++ b/socks5_demo_201909/other/server.cpp @@ -0,0 +1,384 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define SERV_TCP_PORT 9011 /* Local listening port number */ +#define MAX_SIZE 4098 + +using namespace std; + +// simulate socks5-server +// usage: +// 1. "g++ -o server server.cpp" +// 2. "./server" +// 3. "curl -v --socks5 127.0.0.1:9011 https://github.com" => ssl version error(https) +// 4. "curl -v --socks5 127.0.0.1:9011 http://github.com>>g.html" => no error(http ipv4) +// 5. "curl -v --socks5 127.0.0.1:9011 http://www.gnu.org/software/gettext/manual/gettext.html>>ge.html" +// => no error (http ipv6) + +int main() +{ + + int sockfd, newsockfd; + 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(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); + + 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"<h_addr)); + // printf("domin: %s\n",domin_address); + // }else if(addressType==4){//ipv6 + // remote_addr_length=16; + // r_address=new char[16]; + // if (recv(newsockfd, r_address, 16, 0) == -1) { + // cout<<"cannot get the ipv6\n"< +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define SERV_TCP_PORT 9011 /* Local listening port number */ +#define MAX_SIZE 4098 + +using namespace std; + +// simulate socks5-server +// usage: +// 1. "g++ -o server server.cpp" +// 2. "./server" +// 3. "curl -v --socks5 127.0.0.1:9011 https://github.com" => ssl version error(https) +// 4. "curl -v --socks5 127.0.0.1:9011 http://github.com>>g.html" => no error(http ipv4) +// 5. "curl -v --socks5 127.0.0.1:9011 http://www.gnu.org/software/gettext/manual/gettext.html>>ge.html" +// => no error (http ipv6) + +int main() +{ + + int sockfd, newsockfd; + 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 = 0; + +//////////////////////////////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(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); + + 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"<h_addr)); + printf("domin: %s\n",domin_address); + }else if(addressType==4){//ipv6 + remote_addr_length=16; + r_address=new char[16]; + if (recv(newsockfd, r_address, 16, 0) == -1) { + cout<<"cannot get the ipv6\n"< +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define SERV_TCP_PORT 9011 /* Local listening port number */ +#define MAX_SIZE 4098 + +using namespace std; + +// simulate socks5-server +// usage: +// 1. "g++ -o server server.cpp" +// 2. "./server" + +int main() +{ + + int sockfd, newsockfd; + 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 = 0; + +//////////////////////////////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(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); + + 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"<h_addr)); + printf("domin: %s\n",domin_address); + }else if(addressType==4){//ipv6 + remote_addr_length=16; + r_address=new char[16]; + if (recv(newsockfd, r_address, 16, 0) == -1) { + cout<<"cannot get the ipv6\n"< +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define SERV_TCP_PORT 9011 /* Local listening port number */ +#define MAX_SIZE 4098 + +using namespace std; + +int sockfd, newsockfd; + +// simulate socks5-server +// usage: +// 1. "g++ -o server_t server_thread.cpp -lthread" +// 2. "./server_t" + +void * thread_fun1(void * val){ + int local_sockfd=newsockfd; + int remote_sockfd = *((int*)val); + char data[MAX_SIZE]; + int datalen; + while(true){ + datalen=recv(local_sockfd, data, sizeof(data), 0); + if (datalen<0) { + //nothing + }else if(datalen==0){ + break; + }else{ // send to remote server + cout<<"get the data from localhost"<h_addr)); + printf("domin: %s\n",domin_address); + }else if(addressType==4){//ipv6 + remote_addr_length=16; + r_address=new char[16]; + if (recv(newsockfd, r_address, 16, 0) == -1) { + cout<<"cannot get the ipv6\n"< +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define SERV_TCP_PORT 9011 /* Local listening port number */ +#define MAX_SIZE 4098 + +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"<