-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
196 lines (190 loc) · 5.34 KB
/
Copy pathmain.cpp
File metadata and controls
196 lines (190 loc) · 5.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/*
* * Copyright (c) 2019,zhao xi
* All rights reserved.
* Free Dns server for linux
*
*/
#include <stdio.h>
#include<iostream>
#include <boost/thread.hpp>
#include "net/network.h"
#include <tins/tins.h>
#include <iostream>
#include "dns/exception.h"
#include "dns/message.h"
#include "dns/rr.h"
using std::cout;
using std::endl;
using namespace Tins;
PacketSender sender;
#define MAX_MSG 2000
bool callback(const PDU& pdu) {
EthernetII eth = pdu.rfind_pdu<EthernetII>();
IP ip = eth.rfind_pdu<IP>();
UDP udp = ip.rfind_pdu<UDP>();
DNS dns = udp.rfind_pdu<RawPDU>().to<DNS>();
// Is it a DNS query?
if (dns.type() == DNS::QUERY) {
// Let's see if there's any query for an "A" record.
for (const auto& query : dns.queries()) {
if (query.query_type() == DNS::A) {
// Here's one! Let's add an answer.
dns.add_answer(
DNS::resource(query.dname(), "127.0.0.1", DNS::A,
query.query_class(),
// 777 is just a random TTL
777));
}
}
// Have we added some answers?
if (dns.answers_count() > 0) {
// It's a response now
dns.type(DNS::RESPONSE);
// Recursion is available(just in case)
dns.recursion_available(1);
// Build our packet
auto pkt = EthernetII(eth.src_addr(), eth.dst_addr())
/ IP(ip.src_addr(), ip.dst_addr())
/ UDP(udp.sport(), udp.dport()) / dns;
// Send it!
sender.send(pkt);
}
}
return true;
}
using namespace std;
using namespace network;
static std::atomic<unsigned long> packet_times;
void show_status() {
// static int s_show_index = 0;
// if (s_show_index++ % 10 == 0) {
// printf(" index conn \n");
// }
while (1) {
sleep(1);
std::cout << "Send " << packet_times << " packets" << std::endl;
}
}
// 数据处理函数
// @sess session标识
// @data 收到的数据起始指针
// @bytes 收到的数据长度
// @returns: 返回一个size_t, 表示已处理的数据长度. 当返回-1时表示数据错误, 链接即会被关闭.(for tcp )
size_t Tcp_OnMessage(SessionEntry sess, const char* data, size_t bytes) {
// printf("receive: %.*s\n", (int)bytes, data);
sess->Send(data, bytes); // Echo. 将收到的数据原样回传
return bytes;
}
//use tins
size_t TINS_OnMessage(SessionEntry sess, const char* data, size_t bytes) {
// printf("receive: %.*s\n", (int)bytes, data);
++packet_times;
DNS dns(reinterpret_cast<unsigned char *>(const_cast<char *>(data)), bytes);
// for (const auto& query : dns.queries()) {
// cout << query.dname() << std::endl;
// }
// Is it a DNS query?
if (dns.type() == DNS::QUERY) {
// Let's see if there's any query for an "A" record.
for (const auto& query : dns.queries()) {
if (query.query_type() == DNS::A) {
// cout << " Add query A " << std::endl;
// Here's one! Let's add an answer.
dns.add_answer(
DNS::resource(query.dname(), "127.0.0.1", DNS::A,
query.query_class(),
// 777 is just a random TTL
777));
}
}
// Have we added some answers?
if (dns.answers_count() > 0) {
// It's a response now
dns.type(DNS::RESPONSE);
// Recursion is available(just in case)
dns.recursion_available(1);
// Build our packet
// auto pkt = dns;
// Send it!
// sender.send(pkt);
// sess->Send(pkt.records_data_._M_data_ptr(), pkt.records_data_.size());
}
}
sess->Send(data, bytes);
// go [sess,data,bytes]{ sess->Send(data, bytes); } ; // Echo. 将收到的数据原样回传
return 0;
}
//use self dns
size_t OnMessage(SessionEntry sess, const char* data, size_t bytes) {
// printf("receive: %.*s\n", (int)bytes, data);
dns::Message m;
try {
m.decode(data, bytes);
} catch (dns::Exception& e) {
cout << "DNS exception occured when parsing incoming data: " << e.what()
<< endl;
}
++packet_times;
char mesg[MAX_MSG];
// change type of message to response
m.setQr(dns::Message::typeResponse);
/*
// add NAPTR answer
dns::ResourceRecord *rr = new dns::ResourceRecord();
rr->setType(dns::RDATA_NAPTR);
rr->setClass(dns::CLASS_IN);
rr->setTtl(1700);
dns::RDataNAPTR *rdata = new dns::RDataNAPTR();
rdata->setOrder(1);
rdata->setPreference(1);
rdata->setFlags("u");
rdata->setServices("SIP+E2U");
rdata->setRegExp("!.*!domena.cz!");
rdata->setReplacement("");
rr->setRData(rdata);
m.addAnswer(rr);
*/
// add A answer
dns::ResourceRecord *rrA = new dns::ResourceRecord();
rrA->setType(dns::RDATA_A);
rrA->setClass(dns::CLASS_IN);
rrA->setTtl(60);
dns::RDataA *rdataA = new dns::RDataA();
dns::uchar ip4[4] = {'\x01', '\x02', '\x03', '\x04' };
rdataA->setAddress(ip4);
rrA->setRData(rdataA);
m.addAnswer(rrA);
uint mesgSize;
m.encode(mesg, MAX_MSG, mesgSize);
sess->Send(mesg, mesgSize); // Echo. 将收到的数据原样回传
return 0;
}
Server server;
void server_init(){
// Step1: 创建一个Server对象
server.SetReceiveCb(&OnMessage);
boost_ec ec = server.goStart("udp://127.0.0.1:53");
if (ec) {
printf("server start error %d:%s\n", ec.value(), ec.message().c_str());
return;
} else {
printf("server start at %s:%d\n",
server.LocalAddr().address().to_string().c_str(),
server.LocalAddr().port());
}
}
int main() {
server_init();
boost::thread show(&show_status);
// boost::thread_group tg;
// for (int i = 0; i < 4; ++i) {
// tg.create_thread([] {
// //co_sched.RunLoop();
// co_sched.RunUntilNoTask();
// });
// }
// tg.join_all();
co_sched.RunUntilNoTask();
show.join();
return 0;
}