Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
L
libdap-server-udp
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
cellframe
libdap-server-udp
Commits
bc7d3ae4
Commit
bc7d3ae4
authored
5 years ago
by
Roman Khlopkov
🔜
Browse files
Options
Downloads
Patches
Plain Diff
[+] Zone responsibility callbacks added
parent
8a030e58
Branches
features-3330
No related tags found
1 merge request
!7
features-3330
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
dap_dns_server.c
+146
-57
146 additions, 57 deletions
dap_dns_server.c
dap_dns_server.h
+37
-16
37 additions, 16 deletions
dap_dns_server.h
with
183 additions
and
73 deletions
dap_dns_server.c
+
146
−
57
View file @
bc7d3ae4
...
...
@@ -22,10 +22,6 @@
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef _WIN32
#include
<pthread.h>
#endif
#include
"dap_dns_server.h"
#include
"dap_udp_server.h"
#include
"dap_udp_client.h"
...
...
@@ -40,6 +36,9 @@
#define UNUSED(x) (void)(x)
#define LOG_TAG "dap_dns_server"
static
dap_dns_server_t
*
s_dns_server
;
static
char
s_root_alias
[]
=
"dnsroot"
;
/**
* @brief dap_dns_buf_init Initialize DNS parser buffer
* @param buf DNS buffer structure
...
...
@@ -98,10 +97,68 @@ uint32_t dap_dns_resolve_hostname(char *str) {
dap_chain_node_info_t
*
l_node_info
=
(
dap_chain_node_info_t
*
)
l_objs
[
l_node_num
].
value
;
uint32_t
addr
=
l_node_info
->
hdr
.
ext_addr_v4
.
s_addr
;
dap_chain_global_db_objs_delete
(
l_objs
,
l_nodes_count
);
log_it
(
L_DEBUG
,
"DNS resolver find ip %d.%d.%d.%d"
,
addr
&
0xFF
,
(
addr
>>
8
)
&
0xFF
,
(
addr
>>
16
)
&
0xFF
,
(
addr
>>
24
)
&
0xFF
);
log_it
(
L_DEBUG
,
"DNS resolver find ip %d.%d.%d.%d"
,
addr
&
0xFF
,
(
addr
>>
8
)
&
0xFF
,
(
addr
>>
16
)
&
0xFF
,
(
addr
>>
24
)
&
0xFF
);
return
addr
;
}
/**
* @brief dap_dns_zone_register Register DNS zone and set callback to handle it
* @param zone Name of zone to register
* @param callback Callback to handle DNS zone
* @return 0 if success, else return error code
*/
int
dap_dns_zone_register
(
char
*
zone
,
dap_dns_zone_callback_t
callback
)
{
dap_dns_zone_hash_t
*
new_zone
;
HASH_FIND_STR
(
s_dns_server
->
hash_table
,
zone
,
new_zone
);
if
(
new_zone
==
NULL
)
{
// zone is not present
new_zone
=
DAP_NEW
(
dap_dns_zone_hash_t
);
new_zone
->
zone
=
dap_strdup
(
zone
);
HASH_ADD_KEYPTR
(
hh
,
s_dns_server
->
hash_table
,
new_zone
->
zone
,
strlen
(
new_zone
->
zone
),
new_zone
);
}
// if zone present, just reassign callback
new_zone
->
callback
=
callback
;
return
DNS_ERROR_NONE
;
}
/**
* @brief dap_dns_zone_unregister Unregister DNS zone
* @param zone Name of zone to unregister
* @return 0 if success, else return error code
*/
int
dap_dns_zone_unregister
(
char
*
zone
)
{
dap_dns_zone_hash_t
*
asked_zone
;
HASH_FIND_STR
(
s_dns_server
->
hash_table
,
zone
,
asked_zone
);
if
(
asked_zone
==
NULL
)
{
return
DNS_ERROR_NAME
;
}
HASH_DEL
(
s_dns_server
->
hash_table
,
asked_zone
);
DAP_DELETE
(
asked_zone
->
zone
);
DAP_DELETE
(
asked_zone
);
return
DNS_ERROR_NONE
;
}
/**
* @brief dap_dns_zone_find Find callback to registered DNS zone
* @param hostname Name of host for which the zone callback being searched
* @return Callback for registered DNS zone, else return NULL
*/
dap_dns_zone_callback_t
dap_dns_zone_find
(
char
*
hostname
)
{
dap_dns_zone_hash_t
*
asked_zone
;
HASH_FIND_STR
(
s_dns_server
->
hash_table
,
hostname
,
asked_zone
);
if
(
asked_zone
==
NULL
)
{
if
(
!
strcmp
(
hostname
,
&
s_root_alias
[
0
]))
{
return
NULL
;
}
char
*
zone_up
=
strchr
(
hostname
,
'.'
)
+
1
;
if
(
zone_up
==
1
)
{
zone_up
=
&
s_root_alias
[
0
];
}
return
dap_dns_zone_find
(
zone_up
);
}
else
{
return
asked_zone
->
callback
;
}
return
NULL
;
}
/**
* @brief dap_dns_client_read Read and parse incoming DNS message, send reply to it
* @param client DAP client remote structure
...
...
@@ -110,7 +167,6 @@ uint32_t dap_dns_resolve_hostname(char *str) {
*/
void
dap_dns_client_read
(
dap_client_remote_t
*
client
,
void
*
arg
)
{
UNUSED
(
arg
);
if
(
client
->
buf_in_size
<
DNS_HEADER_SIZE
)
{
// Bad request
return
;
}
...
...
@@ -131,17 +187,17 @@ void dap_dns_client_read(dap_client_remote_t *client, void * arg) {
dns_reply
->
ptr
+=
sizeof
(
uint16_t
);
// Put flags later
dap_dns_message_flags_t
msg_flags
;
msg_flags
.
val
=
val
;
dap_dns_message_flags_bits_t
flags
=
msg_flags
.
flags
;
if
(
flags
.
qr
)
{
// It's not request
dap_dns_message_flags_bits_t
*
flags
=
&
msg_flags
.
flags
;
if
(
flags
->
qr
)
{
// It's not request
goto
cleanup
;
}
flags
.
rcode
=
DNS_ERROR_NONE
;
flags
.
qr
=
1
;
// Response bit set
if
(
flags
.
tc
)
{
// Truncated messages not supported yet
flags
.
rcode
=
DNS_ERROR_NOT_SUPPORTED
;
flags
->
rcode
=
DNS_ERROR_NONE
;
flags
->
qr
=
1
;
// Response bit set
if
(
flags
->
tc
)
{
// Truncated messages not supported yet
flags
->
rcode
=
DNS_ERROR_NOT_SUPPORTED
;
}
flags
.
ra
=
0
;
// Recursion not supported yet
flags
.
aa
=
1
;
// Authoritative answer
flags
->
ra
=
0
;
// Recursion not supported yet
flags
->
aa
=
1
;
// Authoritative answer
uint16_t
qdcount
=
dap_dns_buf_get_uint16
(
dns_message
);
dap_dns_buf_put_uint16
(
dns_reply
,
qdcount
);
val
=
dap_dns_buf_get_uint16
(
dns_message
);
// AN count
...
...
@@ -158,58 +214,84 @@ void dap_dns_client_read(dap_client_remote_t *client, void * arg) {
if
(
val
)
{
// No other sections should present
goto
cleanup
;
}
dap_dns_buf_put_uint16
(
dns_reply
,
val
);
dap_dns_buf_put_uint16
(
dns_reply
,
val
);
int
dot_count
=
0
;
dap_string_t
*
dns_hostname
=
dap_string_new
(
""
);
for
(
int
i
=
0
;
i
<
qdcount
;
i
++
)
{
block_len
=
strlen
(
&
dns_message
->
data
[
dns_message
->
ptr
])
+
1
+
2
*
sizeof
(
uint16_t
);
dns_reply
->
data
=
DAP_REALLOC
(
dns_reply
->
data
,
dns_reply
->
ptr
+
block_len
);
memcpy
(
&
dns_reply
->
data
[
dns_reply
->
ptr
],
&
dns_message
->
data
[
dns_message
->
ptr
],
block_len
);
dns_reply
->
ptr
+=
block_len
;
bool
need_dot
=
false
;
while
(
dns_message
->
ptr
<
dns_reply
->
ptr
-
2
*
sizeof
(
uint16_t
))
{
if
(
need_dot
)
{
dap_string_append
(
dns_hostname
,
"."
);
dns_reply
->
ptr
+=
block_len
;
if
(
flags
->
rcode
)
break
;
while
(
dns_message
->
ptr
<
dns_reply
->
ptr
-
2
*
sizeof
(
uint16_t
))
{
uint8_t
len
=
dns_message
->
data
[
dns_message
->
ptr
++
];
if
(
len
>
DNS_MAX_DOMAIN_NAME_LEN
)
{
flags
->
rcode
=
DNS_ERROR_NAME
;
break
;
}
if
(
!
len
)
{
break
;
}
if
(
dot_count
)
{
if
(
dot_count
>
3
)
{
// Max three dots allowed
flags
->
rcode
=
DNS_ERROR_NAME
;
break
;
}
dap_string_append
(
dns_hostname
,
"."
);
}
uint8_t
len
=
dns_message
->
data
[
dns_message
->
ptr
++
];
dap_string_append_len
(
dns_hostname
,
&
dns_message
->
data
[
dns_message
->
ptr
],
len
);
dns_message
->
ptr
+=
len
;
need_dot
=
true
;
dns_message
->
ptr
+=
len
;
dot_count
++
;
if
(
dns_hostname
->
len
>=
DNS_MAX_HOSTNAME_LEN
)
{
flags
->
rcode
=
DNS_ERROR_NAME
;
break
;
}
}
val
=
dap_dns_buf_get_uint16
(
dns_message
);
// DNS record type
if
(
val
!=
DNS_RECORD_TYPE_A
)
{
// Only host address ipv4
flags
.
rcode
=
DNS_ERROR_NOT_SUPPORTED
;
flags
->
rcode
=
DNS_ERROR_NOT_SUPPORTED
;
break
;
}
val
=
dap_dns_buf_get_uint16
(
dns_message
);
// DNS class type
if
(
val
!=
DNS_CLASS_TYPE_IN
)
{
// Internet only
flags
.
rcode
=
DNS_ERROR_NOT_SUPPORTED
;
flags
->
rcode
=
DNS_ERROR_NOT_SUPPORTED
;
break
;
}
if
(
dns_message
->
ptr
!=
dns_reply
->
ptr
)
{
log_it
(
L_ERROR
,
"DNS parser pointer unequal, mptr = %u, rptr = %u"
,
dns_message
->
ptr
,
dns_reply
->
ptr
);
}
}
// Compose DNS answer
block_len
=
DNS_ANSWER_SIZE
;
dns_reply
->
data
=
DAP_REALLOC
(
dns_reply
->
data
,
dns_reply
->
ptr
+
block_len
);
val
=
0xc000
||
DNS_HEADER_SIZE
;
// Link to host name
dap_dns_buf_put_uint16
(
dns_reply
,
val
);
val
=
DNS_RECORD_TYPE_A
;
dap_dns_buf_put_uint16
(
dns_reply
,
val
);
val
=
DNS_CLASS_TYPE_IN
;
dap_dns_buf_put_uint16
(
dns_reply
,
val
);
uint32_t
ttl
=
DNS_TIME_TO_LIVE
;
dap_dns_buf_put_uint32
(
dns_reply
,
ttl
);
val
=
4
;
// RD len for ipv4
dap_dns_buf_put_uint16
(
dns_reply
,
val
);
}
// Find ip addr
uint32_t
ip_addr
=
0
;
if
(
flags
.
rcode
==
DNS_ERROR_NONE
)
{
ip_addr
=
dap_dns_resolve_hostname
(
dns_hostname
->
str
);
}
dap_dns_buf_put_uint32
(
dns_reply
,
ip_addr
);
if
(
flags
->
rcode
==
DNS_ERROR_NONE
)
{
dap_dns_zone_callback_t
callback
=
dap_dns_zone_find
(
dns_hostname
->
str
);
if
(
callback
)
{
ip_addr
=
callback
(
dns_hostname
->
str
);
}
}
if
(
ip_addr
)
{
// Compose DNS answer
block_len
=
DNS_ANSWER_SIZE
;
dns_reply
->
data
=
DAP_REALLOC
(
dns_reply
->
data
,
dns_reply
->
ptr
+
block_len
);
val
=
0xc000
||
DNS_HEADER_SIZE
;
// Link to host name
dap_dns_buf_put_uint16
(
dns_reply
,
val
);
val
=
DNS_RECORD_TYPE_A
;
dap_dns_buf_put_uint16
(
dns_reply
,
val
);
val
=
DNS_CLASS_TYPE_IN
;
dap_dns_buf_put_uint16
(
dns_reply
,
val
);
uint32_t
ttl
=
DNS_TIME_TO_LIVE
;
dap_dns_buf_put_uint32
(
dns_reply
,
ttl
);
val
=
4
;
// RD len for ipv4
dap_dns_buf_put_uint16
(
dns_reply
,
val
);
dap_dns_buf_put_uint32
(
dns_reply
,
ip_addr
);
}
else
if
(
flags
->
rcode
==
DNS_ERROR_NONE
)
{
flags
->
rcode
=
DNS_ERROR_NAME
;
}
if
(
flags
->
rcode
)
{
dns_reply
->
data
[
7
]
=
0
;
// No answer section
}
// Set reply flags
msg_flags
.
flags
=
flags
;
dns_reply
->
data
[
2
]
=
msg_flags
.
val
>>
8
;
dns_reply
->
data
[
3
]
=
msg_flags
.
val
;
// Send DNS reply
...
...
@@ -224,18 +306,25 @@ cleanup:
return
;
}
dap_server_t
*
dap_dns_server_start
()
{
pthread_t
tDNSThread
;
dap_server_t
*
sh
=
dap_udp_server_listen
(
DNS_LISTEN_PORT
);
sh
->
client_read_callback
=
*
dap_dns_client_read
;
sh
->
client_write_callback
=
NULL
;
sh
->
client_new_callback
=
NULL
;
sh
->
client_delete_callback
=
NULL
;
pthread_create
(
&
tDNSThread
,
NULL
,
(
void
*
)
dap_udp_server_loop
,
sh
);
return
sh
;
void
dap_dns_server_start
()
{
s_dns_server
=
DAP_NEW
(
dap_dns_server_t
);
s_dns_server
->
hash_table
=
NULL
;
s_dns_server
->
instance
=
dap_udp_server_listen
(
DNS_LISTEN_PORT
);
s_dns_server
->
instance
->
client_read_callback
=
*
dap_dns_client_read
;
s_dns_server
->
instance
->
client_write_callback
=
NULL
;
s_dns_server
->
instance
->
client_new_callback
=
NULL
;
s_dns_server
->
instance
->
client_delete_callback
=
NULL
;
dap_dns_zone_register
(
&
s_root_alias
[
0
],
dap_dns_resolve_hostname
);
// root resolver
pthread_create
(
&
s_dns_server
->
udp_thread
,
NULL
,
(
void
*
)
dap_udp_server_loop
,
s_dns_server
->
instance
);
}
void
dap_dns_server_stop
(
dap_server_t
*
sh
)
{
// TODO add deinit code to dac_udp_server
dap_udp_server_delete
(
sh
);
void
dap_dns_server_stop
()
{
dap_dns_zone_hash_t
*
current_zone
,
*
tmp
;
HASH_ITER
(
hh
,
s_dns_server
->
hash_table
,
current_zone
,
tmp
)
{
HASH_DEL
(
s_dns_server
->
hash_table
,
current_zone
);
DAP_DELETE
(
current_zone
->
zone
);
DAP_DELETE
(
current_zone
);
}
// TODO add code to stop udp_thread
dap_udp_server_delete
(
s_dns_server
->
instance
);
}
This diff is collapsed.
Click to expand it.
dap_dns_server.h
+
37
−
16
View file @
bc7d3ae4
...
...
@@ -24,12 +24,18 @@
#pragma once
#ifdef _WIN32
#include
<pthread.h>
#endif
#include
"dap_server.h"
#include
"uthash.h"
#define DNS_LISTEN_PORT 53 // UDP
#define DNS_TIME_TO_LIVE 600 // Seconds
#define DNS_HEADER_SIZE 12
#define DNS_ANSWER_SIZE 16
#define DNS_ANSWER_SIZE 16
#define DNS_MAX_HOSTNAME_LEN 255
#define DNS_MAX_DOMAIN_NAME_LEN 63
typedef
enum
_dap_dns_query_type_t
{
DNS_QUERY_TYPE_STANDARD
,
...
...
@@ -41,9 +47,9 @@ typedef enum _dap_dns_error_t {
DNS_ERROR_NONE
,
// No error
DNS_ERROR_FORMAT
,
// DNS message parsing error
DNS_ERROR_FAILURE
,
// Internal server error
DNS_ERROR_NAME
,
// Only for authoritative servers. Name does no
r
exist
DNS_ERROR_NAME
,
// Only for authoritative servers. Name does no
t
exist
DNS_ERROR_NOT_SUPPORTED
,
// This kind of query not implemented
DNS_ERROR_REFUSED
// Operation re
s
fused
DNS_ERROR_REFUSED
// Operation refused
}
dap_dns_error_t
;
typedef
enum
_dap_dns_record_type_t
{
...
...
@@ -79,26 +85,41 @@ typedef enum _dap_dns_class_type_t {
}
dap_dns_class_type_t
;
typedef
struct
_dap_dns_message_flags_bits_t
{
uint16_t
id
;
// message identifier
uint16_t
qr
:
1
;
// 0 - query, 1 - response
uint16_t
opcode
:
4
;
// type of query, copied to answer: 0 - standard, 1 - inverse, 2 - status, 3-15 - reserved
uint16_t
aa
:
1
;
// 1 - authoritative answer (answer only)
uint16_t
tc
:
1
;
// 1 - message truncated
uint16_t
rd
:
1
;
// 1 - recursion desired (query set, copied to answer)
uint16_t
ra
:
1
;
// 1 - recursion available (answer only)
uint16_t
z
:
3
;
// reserved, must be zero
uint16_t
rcode
:
4
;
// response code, answer only: 0 - no error, 1 - format error, 2 - server failure, 3 - name error, 4 - not supported, 5 - refused
int
rcode
:
4
;
// response code, answer only: 0 - no error, 1 - format error, 2 - server failure, 3 - name error, 4 - not supported, 5 - refused
int
z
:
3
;
// reserved, must be zero
int
ra
:
1
;
// 1 - recursion available (answer only)
int
rd
:
1
;
// 1 - recursion desired (query set, copied to answer)
int
tc
:
1
;
// 1 - message truncated
int
aa
:
1
;
// 1 - authoritative answer (answer only)
int
opcode
:
4
;
// type of query, copied to answer: 0 - standard, 1 - inverse, 2 - status, 3-15 - reserved
int
qr
:
1
;
// 0 - query, 1 - response
}
dap_dns_message_flags_bits_t
;
typedef
uint32_t
(
*
dap_dns_zone_callback_t
)
(
char
*
hostname
);
// Callback for DNS zone operations
typedef
union
_dap_dns_message_flags_t
{
dap_dns_message_flags_bits_t
flags
;
u
int
16_t
val
;
int
val
;
}
dap_dns_message_flags_t
;
typedef
struct
_dap_dns_bu
t
_t
{
typedef
struct
_dap_dns_bu
f
_t
{
char
*
data
;
uint32_t
ptr
;
}
dap_dns_buf_t
;
dap_server_t
*
dap_dns_server_start
();
void
dap_dns_server_stop
(
dap_server_t
*
sh
);
typedef
struct
_dap_dns_zone_hash_t
{
char
*
zone
;
dap_dns_zone_callback_t
callback
;
UT_hash_handle
hh
;
}
dap_dns_zone_hash_t
;
typedef
struct
_dap_dns_server_t
{
dap_server_t
*
instance
;
pthread_t
udp_thread
;
dap_dns_zone_hash_t
*
hash_table
;
}
dap_dns_server_t
;
void
dap_dns_server_start
();
void
dap_dns_server_stop
();
int
dap_dns_zone_register
(
char
*
zone
,
dap_dns_zone_callback_t
callback
);
int
dap_dns_zone_unregister
(
char
*
zone
);
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment