mirror of
https://github.com/cesanta/mongoose.git
synced 2025-06-08 01:42:52 +08:00
s/dmg/dns/g
PUBLISHED_FROM=96dc8b0b4001f2206749a401c615f043fc5f6131
This commit is contained in:
parent
dcd4e660a3
commit
1eaabdd8e5
@ -61,7 +61,7 @@ static uint8_t board_ip[] = {192, 168, 10, 177};
|
|||||||
#ifdef WIFI_CC3000
|
#ifdef WIFI_CC3000
|
||||||
static uint8_t subnet_mask[] = {255, 255, 255, 0};
|
static uint8_t subnet_mask[] = {255, 255, 255, 0};
|
||||||
static uint8_t gateway[] = {192, 168, 10, 254};
|
static uint8_t gateway[] = {192, 168, 10, 254};
|
||||||
static uint8_t dmg_ip[] = {192, 168, 10, 254};
|
static uint8_t dns_ip[] = {192, 168, 10, 254};
|
||||||
|
|
||||||
static const char *wlan_ssid = "mynetwork";
|
static const char *wlan_ssid = "mynetwork";
|
||||||
static const char *wlan_pwd = "mypassword";
|
static const char *wlan_pwd = "mypassword";
|
||||||
@ -117,7 +117,7 @@ void setup()
|
|||||||
avr_netinit(board_mac, board_ip);
|
avr_netinit(board_mac, board_ip);
|
||||||
#elif defined(WIFI_CC3000)
|
#elif defined(WIFI_CC3000)
|
||||||
if (avr_netinit(wlan_ssid, wlan_pwd, wlan_security, IP2U32(board_ip),
|
if (avr_netinit(wlan_ssid, wlan_pwd, wlan_security, IP2U32(board_ip),
|
||||||
IP2U32(subnet_mask), IP2U32(gateway), IP2U32(dmg_ip)) != 0) {
|
IP2U32(subnet_mask), IP2U32(gateway), IP2U32(dns_ip)) != 0) {
|
||||||
Serial.println("Initialization error, check network settings");
|
Serial.println("Initialization error, check network settings");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -59,7 +59,7 @@ static uint8_t board_ip[] = {192, 168, 10, 8};
|
|||||||
#ifdef WIFI_CC3000
|
#ifdef WIFI_CC3000
|
||||||
static uint8_t subnet_mask[] = {255, 255, 255, 0};
|
static uint8_t subnet_mask[] = {255, 255, 255, 0};
|
||||||
static uint8_t gateway[] = {192, 168, 10, 254};
|
static uint8_t gateway[] = {192, 168, 10, 254};
|
||||||
static uint8_t dmg_ip[] = {192, 168, 10, 254};
|
static uint8_t dns_ip[] = {192, 168, 10, 254};
|
||||||
|
|
||||||
static const char *wlan_ssid = "mynetwork";
|
static const char *wlan_ssid = "mynetwork";
|
||||||
static const char *wlan_pwd = "mypassword";
|
static const char *wlan_pwd = "mypassword";
|
||||||
@ -116,7 +116,7 @@ void setup() {
|
|||||||
avr_netinit(board_mac, board_ip);
|
avr_netinit(board_mac, board_ip);
|
||||||
#elif defined(WIFI_CC3000)
|
#elif defined(WIFI_CC3000)
|
||||||
if (avr_netinit(wlan_ssid, wlan_pwd, wlan_security, IP2U32(board_ip),
|
if (avr_netinit(wlan_ssid, wlan_pwd, wlan_security, IP2U32(board_ip),
|
||||||
IP2U32(subnet_mask), IP2U32(gateway), IP2U32(dmg_ip)) != 0) {
|
IP2U32(subnet_mask), IP2U32(gateway), IP2U32(dns_ip)) != 0) {
|
||||||
Serial.println("Initialization error, check network settings");
|
Serial.println("Initialization error, check network settings");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -17,20 +17,20 @@ static in_addr_t s_our_ip_addr;
|
|||||||
static const char *s_listening_addr = "udp://:5533";
|
static const char *s_listening_addr = "udp://:5533";
|
||||||
|
|
||||||
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||||
struct mg_dmg_message *msg;
|
struct mg_dns_message *msg;
|
||||||
struct mg_dmg_resource_record *rr;
|
struct mg_dns_resource_record *rr;
|
||||||
struct mg_dmg_reply reply;
|
struct mg_dns_reply reply;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
switch (ev) {
|
switch (ev) {
|
||||||
case MG_DNS_MESSAGE:
|
case MG_DNS_MESSAGE:
|
||||||
msg = (struct mg_dmg_message *) ev_data;
|
msg = (struct mg_dns_message *) ev_data;
|
||||||
reply = mg_dmg_create_reply(&nc->send_mbuf, msg);
|
reply = mg_dns_create_reply(&nc->send_mbuf, msg);
|
||||||
|
|
||||||
for (i = 0; i < msg->num_questions; i++) {
|
for (i = 0; i < msg->num_questions; i++) {
|
||||||
rr = &msg->questions[i];
|
rr = &msg->questions[i];
|
||||||
if (rr->rtype == MG_DNS_A_RECORD) {
|
if (rr->rtype == MG_DNS_A_RECORD) {
|
||||||
mg_dmg_reply_record(&reply, rr, NULL, rr->rtype, 3600,
|
mg_dns_reply_record(&reply, rr, NULL, rr->rtype, 3600,
|
||||||
&s_our_ip_addr, 4);
|
&s_our_ip_addr, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||||||
* See http://goo.gl/QWvufr for a distinction between NXDOMAIN and NODATA.
|
* See http://goo.gl/QWvufr for a distinction between NXDOMAIN and NODATA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mg_dmg_send_reply(nc, &reply);
|
mg_dns_send_reply(nc, &reply);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
130
mongoose.c
130
mongoose.c
@ -3018,7 +3018,7 @@ MG_INTERNAL struct mg_connection *mg_finish_connect(struct mg_connection *nc,
|
|||||||
* either failure (and dealloc the connection)
|
* either failure (and dealloc the connection)
|
||||||
* or success (and proceed with connect()
|
* or success (and proceed with connect()
|
||||||
*/
|
*/
|
||||||
static void resolve_cb(struct mg_dmg_message *msg, void *data) {
|
static void resolve_cb(struct mg_dns_message *msg, void *data) {
|
||||||
struct mg_connection *nc = (struct mg_connection *) data;
|
struct mg_connection *nc = (struct mg_connection *) data;
|
||||||
int i;
|
int i;
|
||||||
int failure = -1;
|
int failure = -1;
|
||||||
@ -3034,7 +3034,7 @@ static void resolve_cb(struct mg_dmg_message *msg, void *data) {
|
|||||||
* Async resolver guarantees that there is at least one answer.
|
* Async resolver guarantees that there is at least one answer.
|
||||||
* TODO(lsm): handle IPv6 answers too
|
* TODO(lsm): handle IPv6 answers too
|
||||||
*/
|
*/
|
||||||
mg_dmg_parse_record_data(msg, &msg->answers[i], &nc->sa.sin.sin_addr,
|
mg_dns_parse_record_data(msg, &msg->answers[i], &nc->sa.sin.sin_addr,
|
||||||
4);
|
4);
|
||||||
/* Make mg_finish_connect() trigger MG_EV_CONNECT on failure */
|
/* Make mg_finish_connect() trigger MG_EV_CONNECT on failure */
|
||||||
nc->flags |= MG_F_CONNECTING;
|
nc->flags |= MG_F_CONNECTING;
|
||||||
@ -6911,9 +6911,9 @@ struct mg_mqtt_session *mg_mqtt_next(struct mg_mqtt_broker *brk,
|
|||||||
|
|
||||||
#define MAX_DNS_PACKET_LEN 2048
|
#define MAX_DNS_PACKET_LEN 2048
|
||||||
|
|
||||||
static int mg_dmg_tid = 0xa0;
|
static int mg_dns_tid = 0xa0;
|
||||||
|
|
||||||
struct mg_dmg_header {
|
struct mg_dns_header {
|
||||||
uint16_t transaction_id;
|
uint16_t transaction_id;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
uint16_t num_questions;
|
uint16_t num_questions;
|
||||||
@ -6922,10 +6922,10 @@ struct mg_dmg_header {
|
|||||||
uint16_t num_other_prs;
|
uint16_t num_other_prs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mg_dmg_resource_record *mg_dmg_next_record(
|
struct mg_dns_resource_record *mg_dns_next_record(
|
||||||
struct mg_dmg_message *msg, int query,
|
struct mg_dns_message *msg, int query,
|
||||||
struct mg_dmg_resource_record *prev) {
|
struct mg_dns_resource_record *prev) {
|
||||||
struct mg_dmg_resource_record *rr;
|
struct mg_dns_resource_record *rr;
|
||||||
|
|
||||||
for (rr = (prev == NULL ? msg->answers : prev + 1);
|
for (rr = (prev == NULL ? msg->answers : prev + 1);
|
||||||
rr - msg->answers < msg->num_answers; rr++) {
|
rr - msg->answers < msg->num_answers; rr++) {
|
||||||
@ -6936,8 +6936,8 @@ struct mg_dmg_resource_record *mg_dmg_next_record(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_dmg_parse_record_data(struct mg_dmg_message *msg,
|
int mg_dns_parse_record_data(struct mg_dns_message *msg,
|
||||||
struct mg_dmg_resource_record *rr, void *data,
|
struct mg_dns_resource_record *rr, void *data,
|
||||||
size_t data_len) {
|
size_t data_len) {
|
||||||
switch (rr->rtype) {
|
switch (rr->rtype) {
|
||||||
case MG_DNS_A_RECORD:
|
case MG_DNS_A_RECORD:
|
||||||
@ -6958,16 +6958,16 @@ int mg_dmg_parse_record_data(struct mg_dmg_message *msg,
|
|||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
case MG_DNS_CNAME_RECORD:
|
case MG_DNS_CNAME_RECORD:
|
||||||
mg_dmg_uncompress_name(msg, &rr->rdata, (char *) data, data_len);
|
mg_dns_uncompress_name(msg, &rr->rdata, (char *) data, data_len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_dmg_insert_header(struct mbuf *io, size_t pos,
|
int mg_dns_insert_header(struct mbuf *io, size_t pos,
|
||||||
struct mg_dmg_message *msg) {
|
struct mg_dns_message *msg) {
|
||||||
struct mg_dmg_header header;
|
struct mg_dns_header header;
|
||||||
|
|
||||||
memset(&header, 0, sizeof(header));
|
memset(&header, 0, sizeof(header));
|
||||||
header.transaction_id = msg->transaction_id;
|
header.transaction_id = msg->transaction_id;
|
||||||
@ -6978,12 +6978,12 @@ int mg_dmg_insert_header(struct mbuf *io, size_t pos,
|
|||||||
return mbuf_insert(io, pos, &header, sizeof(header));
|
return mbuf_insert(io, pos, &header, sizeof(header));
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_dmg_copy_body(struct mbuf *io, struct mg_dmg_message *msg) {
|
int mg_dns_copy_body(struct mbuf *io, struct mg_dns_message *msg) {
|
||||||
return mbuf_append(io, msg->pkt.p + sizeof(struct mg_dmg_header),
|
return mbuf_append(io, msg->pkt.p + sizeof(struct mg_dns_header),
|
||||||
msg->pkt.len - sizeof(struct mg_dmg_header));
|
msg->pkt.len - sizeof(struct mg_dns_header));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mg_dmg_encode_name(struct mbuf *io, const char *name, size_t len) {
|
static int mg_dns_encode_name(struct mbuf *io, const char *name, size_t len) {
|
||||||
const char *s;
|
const char *s;
|
||||||
unsigned char n;
|
unsigned char n;
|
||||||
size_t pos = io->len;
|
size_t pos = io->len;
|
||||||
@ -7012,7 +7012,7 @@ static int mg_dmg_encode_name(struct mbuf *io, const char *name, size_t len) {
|
|||||||
return io->len - pos;
|
return io->len - pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_dmg_encode_record(struct mbuf *io, struct mg_dmg_resource_record *rr,
|
int mg_dns_encode_record(struct mbuf *io, struct mg_dns_resource_record *rr,
|
||||||
const char *name, size_t nlen, const void *rdata,
|
const char *name, size_t nlen, const void *rdata,
|
||||||
size_t rlen) {
|
size_t rlen) {
|
||||||
size_t pos = io->len;
|
size_t pos = io->len;
|
||||||
@ -7023,7 +7023,7 @@ int mg_dmg_encode_record(struct mbuf *io, struct mg_dmg_resource_record *rr,
|
|||||||
return -1; /* LCOV_EXCL_LINE */
|
return -1; /* LCOV_EXCL_LINE */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mg_dmg_encode_name(io, name, nlen) == -1) {
|
if (mg_dns_encode_name(io, name, nlen) == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7041,7 +7041,7 @@ int mg_dmg_encode_record(struct mbuf *io, struct mg_dmg_resource_record *rr,
|
|||||||
/* fill size after encoding */
|
/* fill size after encoding */
|
||||||
size_t off = io->len;
|
size_t off = io->len;
|
||||||
mbuf_append(io, &u16, 2);
|
mbuf_append(io, &u16, 2);
|
||||||
if ((clen = mg_dmg_encode_name(io, (const char *) rdata, rlen)) == -1) {
|
if ((clen = mg_dns_encode_name(io, (const char *) rdata, rlen)) == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
u16 = clen;
|
u16 = clen;
|
||||||
@ -7057,28 +7057,28 @@ int mg_dmg_encode_record(struct mbuf *io, struct mg_dmg_resource_record *rr,
|
|||||||
return io->len - pos;
|
return io->len - pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_send_dmg_query(struct mg_connection *nc, const char *name,
|
void mg_send_dns_query(struct mg_connection *nc, const char *name,
|
||||||
int query_type) {
|
int query_type) {
|
||||||
struct mg_dmg_message *msg =
|
struct mg_dns_message *msg =
|
||||||
(struct mg_dmg_message *) MG_CALLOC(1, sizeof(*msg));
|
(struct mg_dns_message *) MG_CALLOC(1, sizeof(*msg));
|
||||||
struct mbuf pkt;
|
struct mbuf pkt;
|
||||||
struct mg_dmg_resource_record *rr = &msg->questions[0];
|
struct mg_dns_resource_record *rr = &msg->questions[0];
|
||||||
|
|
||||||
DBG(("%s %d", name, query_type));
|
DBG(("%s %d", name, query_type));
|
||||||
|
|
||||||
mbuf_init(&pkt, MAX_DNS_PACKET_LEN);
|
mbuf_init(&pkt, MAX_DNS_PACKET_LEN);
|
||||||
|
|
||||||
msg->transaction_id = ++mg_dmg_tid;
|
msg->transaction_id = ++mg_dns_tid;
|
||||||
msg->flags = 0x100;
|
msg->flags = 0x100;
|
||||||
msg->num_questions = 1;
|
msg->num_questions = 1;
|
||||||
|
|
||||||
mg_dmg_insert_header(&pkt, 0, msg);
|
mg_dns_insert_header(&pkt, 0, msg);
|
||||||
|
|
||||||
rr->rtype = query_type;
|
rr->rtype = query_type;
|
||||||
rr->rclass = 1; /* Class: inet */
|
rr->rclass = 1; /* Class: inet */
|
||||||
rr->kind = MG_DNS_QUESTION;
|
rr->kind = MG_DNS_QUESTION;
|
||||||
|
|
||||||
if (mg_dmg_encode_record(&pkt, rr, name, strlen(name), NULL, 0) == -1) {
|
if (mg_dns_encode_record(&pkt, rr, name, strlen(name), NULL, 0) == -1) {
|
||||||
/* TODO(mkm): return an error code */
|
/* TODO(mkm): return an error code */
|
||||||
goto cleanup; /* LCOV_EXCL_LINE */
|
goto cleanup; /* LCOV_EXCL_LINE */
|
||||||
}
|
}
|
||||||
@ -7096,8 +7096,8 @@ cleanup:
|
|||||||
MG_FREE(msg);
|
MG_FREE(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char *mg_parse_dmg_resource_record(
|
static unsigned char *mg_parse_dns_resource_record(
|
||||||
unsigned char *data, unsigned char *end, struct mg_dmg_resource_record *rr,
|
unsigned char *data, unsigned char *end, struct mg_dns_resource_record *rr,
|
||||||
int reply) {
|
int reply) {
|
||||||
unsigned char *name = data;
|
unsigned char *name = data;
|
||||||
int chunk_len, data_len;
|
int chunk_len, data_len;
|
||||||
@ -7144,8 +7144,8 @@ static unsigned char *mg_parse_dmg_resource_record(
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_parse_dns(const char *buf, int len, struct mg_dmg_message *msg) {
|
int mg_parse_dns(const char *buf, int len, struct mg_dns_message *msg) {
|
||||||
struct mg_dmg_header *header = (struct mg_dmg_header *) buf;
|
struct mg_dns_header *header = (struct mg_dns_header *) buf;
|
||||||
unsigned char *data = (unsigned char *) buf + sizeof(*header);
|
unsigned char *data = (unsigned char *) buf + sizeof(*header);
|
||||||
unsigned char *end = (unsigned char *) buf + len;
|
unsigned char *end = (unsigned char *) buf + len;
|
||||||
int i;
|
int i;
|
||||||
@ -7163,17 +7163,17 @@ int mg_parse_dns(const char *buf, int len, struct mg_dmg_message *msg) {
|
|||||||
|
|
||||||
for (i = 0; i < msg->num_questions && i < (int) ARRAY_SIZE(msg->questions);
|
for (i = 0; i < msg->num_questions && i < (int) ARRAY_SIZE(msg->questions);
|
||||||
i++) {
|
i++) {
|
||||||
data = mg_parse_dmg_resource_record(data, end, &msg->questions[i], 0);
|
data = mg_parse_dns_resource_record(data, end, &msg->questions[i], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < msg->num_answers && i < (int) ARRAY_SIZE(msg->answers); i++) {
|
for (i = 0; i < msg->num_answers && i < (int) ARRAY_SIZE(msg->answers); i++) {
|
||||||
data = mg_parse_dmg_resource_record(data, end, &msg->answers[i], 1);
|
data = mg_parse_dns_resource_record(data, end, &msg->answers[i], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t mg_dmg_uncompress_name(struct mg_dmg_message *msg, struct mg_str *name,
|
size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name,
|
||||||
char *dst, int dst_len) {
|
char *dst, int dst_len) {
|
||||||
int chunk_len;
|
int chunk_len;
|
||||||
char *old_dst = dst;
|
char *old_dst = dst;
|
||||||
@ -7222,9 +7222,9 @@ size_t mg_dmg_uncompress_name(struct mg_dmg_message *msg, struct mg_str *name,
|
|||||||
return dst - old_dst;
|
return dst - old_dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dmg_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
static void dns_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||||
struct mbuf *io = &nc->recv_mbuf;
|
struct mbuf *io = &nc->recv_mbuf;
|
||||||
struct mg_dmg_message msg;
|
struct mg_dns_message msg;
|
||||||
|
|
||||||
/* Pass low-level events to the user handler */
|
/* Pass low-level events to the user handler */
|
||||||
nc->handler(nc, ev, ev_data);
|
nc->handler(nc, ev, ev_data);
|
||||||
@ -7238,7 +7238,7 @@ static void dmg_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||||||
/* reply + recursion allowed + format error */
|
/* reply + recursion allowed + format error */
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
msg.flags = 0x8081;
|
msg.flags = 0x8081;
|
||||||
mg_dmg_insert_header(io, 0, &msg);
|
mg_dns_insert_header(io, 0, &msg);
|
||||||
if (!(nc->flags & MG_F_UDP)) {
|
if (!(nc->flags & MG_F_UDP)) {
|
||||||
uint16_t len = htons(io->len);
|
uint16_t len = htons(io->len);
|
||||||
mbuf_insert(io, 0, &len, 2);
|
mbuf_insert(io, 0, &len, 2);
|
||||||
@ -7254,7 +7254,7 @@ static void dmg_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void mg_set_protocol_dns(struct mg_connection *nc) {
|
void mg_set_protocol_dns(struct mg_connection *nc) {
|
||||||
nc->proto_handler = dmg_handler;
|
nc->proto_handler = dns_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MG_DISABLE_DNS */
|
#endif /* MG_DISABLE_DNS */
|
||||||
@ -7271,24 +7271,24 @@ void mg_set_protocol_dns(struct mg_connection *nc) {
|
|||||||
|
|
||||||
/* Amalgamated: #include "internal.h" */
|
/* Amalgamated: #include "internal.h" */
|
||||||
|
|
||||||
struct mg_dmg_reply mg_dmg_create_reply(struct mbuf *io,
|
struct mg_dns_reply mg_dns_create_reply(struct mbuf *io,
|
||||||
struct mg_dmg_message *msg) {
|
struct mg_dns_message *msg) {
|
||||||
struct mg_dmg_reply rep;
|
struct mg_dns_reply rep;
|
||||||
rep.msg = msg;
|
rep.msg = msg;
|
||||||
rep.io = io;
|
rep.io = io;
|
||||||
rep.start = io->len;
|
rep.start = io->len;
|
||||||
|
|
||||||
/* reply + recursion allowed */
|
/* reply + recursion allowed */
|
||||||
msg->flags |= 0x8080;
|
msg->flags |= 0x8080;
|
||||||
mg_dmg_copy_body(io, msg);
|
mg_dns_copy_body(io, msg);
|
||||||
|
|
||||||
msg->num_answers = 0;
|
msg->num_answers = 0;
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_dmg_send_reply(struct mg_connection *nc, struct mg_dmg_reply *r) {
|
int mg_dns_send_reply(struct mg_connection *nc, struct mg_dns_reply *r) {
|
||||||
size_t sent = r->io->len - r->start;
|
size_t sent = r->io->len - r->start;
|
||||||
mg_dmg_insert_header(r->io, r->start, r->msg);
|
mg_dns_insert_header(r->io, r->start, r->msg);
|
||||||
if (!(nc->flags & MG_F_UDP)) {
|
if (!(nc->flags & MG_F_UDP)) {
|
||||||
uint16_t len = htons(sent);
|
uint16_t len = htons(sent);
|
||||||
mbuf_insert(r->io, r->start, &len, 2);
|
mbuf_insert(r->io, r->start, &len, 2);
|
||||||
@ -7301,13 +7301,13 @@ int mg_dmg_send_reply(struct mg_connection *nc, struct mg_dmg_reply *r) {
|
|||||||
return sent;
|
return sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mg_dmg_reply_record(struct mg_dmg_reply *reply,
|
int mg_dns_reply_record(struct mg_dns_reply *reply,
|
||||||
struct mg_dmg_resource_record *question,
|
struct mg_dns_resource_record *question,
|
||||||
const char *name, int rtype, int ttl, const void *rdata,
|
const char *name, int rtype, int ttl, const void *rdata,
|
||||||
size_t rdata_len) {
|
size_t rdata_len) {
|
||||||
struct mg_dmg_message *msg = (struct mg_dmg_message *) reply->msg;
|
struct mg_dns_message *msg = (struct mg_dns_message *) reply->msg;
|
||||||
char rname[512];
|
char rname[512];
|
||||||
struct mg_dmg_resource_record *ans = &msg->answers[msg->num_answers];
|
struct mg_dns_resource_record *ans = &msg->answers[msg->num_answers];
|
||||||
if (msg->num_answers >= MG_MAX_DNS_ANSWERS) {
|
if (msg->num_answers >= MG_MAX_DNS_ANSWERS) {
|
||||||
return -1; /* LCOV_EXCL_LINE */
|
return -1; /* LCOV_EXCL_LINE */
|
||||||
}
|
}
|
||||||
@ -7315,7 +7315,7 @@ int mg_dmg_reply_record(struct mg_dmg_reply *reply,
|
|||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
name = rname;
|
name = rname;
|
||||||
rname[511] = 0;
|
rname[511] = 0;
|
||||||
mg_dmg_uncompress_name(msg, &question->name, rname, sizeof(rname) - 1);
|
mg_dns_uncompress_name(msg, &question->name, rname, sizeof(rname) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
*ans = *question;
|
*ans = *question;
|
||||||
@ -7323,7 +7323,7 @@ int mg_dmg_reply_record(struct mg_dmg_reply *reply,
|
|||||||
ans->rtype = rtype;
|
ans->rtype = rtype;
|
||||||
ans->ttl = ttl;
|
ans->ttl = ttl;
|
||||||
|
|
||||||
if (mg_dmg_encode_record(reply->io, ans, name, strlen(name), rdata,
|
if (mg_dns_encode_record(reply->io, ans, name, strlen(name), rdata,
|
||||||
rdata_len) == -1) {
|
rdata_len) == -1) {
|
||||||
return -1; /* LCOV_EXCL_LINE */
|
return -1; /* LCOV_EXCL_LINE */
|
||||||
};
|
};
|
||||||
@ -7350,9 +7350,9 @@ int mg_dmg_reply_record(struct mg_dmg_reply *reply,
|
|||||||
#define MG_DEFAULT_NAMESERVER "8.8.8.8"
|
#define MG_DEFAULT_NAMESERVER "8.8.8.8"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char *mg_default_dmg_server = "udp://" MG_DEFAULT_NAMESERVER ":53";
|
static const char *mg_default_dns_server = "udp://" MG_DEFAULT_NAMESERVER ":53";
|
||||||
|
|
||||||
MG_INTERNAL char mg_dmg_server[256];
|
MG_INTERNAL char mg_dns_server[256];
|
||||||
|
|
||||||
struct mg_resolve_async_request {
|
struct mg_resolve_async_request {
|
||||||
char name[1024];
|
char name[1024];
|
||||||
@ -7435,7 +7435,7 @@ static int mg_get_ip_address_of_nameserver(char *name, size_t name_len) {
|
|||||||
(void) fclose(fp);
|
(void) fclose(fp);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
snprintf(name, name_len, "%s", mg_default_dmg_server);
|
snprintf(name, name_len, "%s", mg_default_dns_server);
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -7480,7 +7480,7 @@ int mg_resolve_from_hosts_file(const char *name, union socket_address *usa) {
|
|||||||
static void mg_resolve_async_eh(struct mg_connection *nc, int ev, void *data) {
|
static void mg_resolve_async_eh(struct mg_connection *nc, int ev, void *data) {
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
struct mg_resolve_async_request *req;
|
struct mg_resolve_async_request *req;
|
||||||
struct mg_dmg_message *msg;
|
struct mg_dns_message *msg;
|
||||||
|
|
||||||
DBG(("ev=%d", ev));
|
DBG(("ev=%d", ev));
|
||||||
|
|
||||||
@ -7496,13 +7496,13 @@ static void mg_resolve_async_eh(struct mg_connection *nc, int ev, void *data) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (now - req->last_time > req->timeout) {
|
if (now - req->last_time > req->timeout) {
|
||||||
mg_send_dmg_query(nc, req->name, req->query);
|
mg_send_dns_query(nc, req->name, req->query);
|
||||||
req->last_time = now;
|
req->last_time = now;
|
||||||
req->retries++;
|
req->retries++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MG_EV_RECV:
|
case MG_EV_RECV:
|
||||||
msg = (struct mg_dmg_message *) MG_MALLOC(sizeof(*msg));
|
msg = (struct mg_dns_message *) MG_MALLOC(sizeof(*msg));
|
||||||
if (mg_parse_dns(nc->recv_mbuf.buf, *(int *) data, msg) == 0 &&
|
if (mg_parse_dns(nc->recv_mbuf.buf, *(int *) data, msg) == 0 &&
|
||||||
msg->num_answers > 0) {
|
msg->num_answers > 0) {
|
||||||
req->callback(msg, req->data);
|
req->callback(msg, req->data);
|
||||||
@ -7526,7 +7526,7 @@ int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,
|
|||||||
mg_resolve_callback_t cb, void *data,
|
mg_resolve_callback_t cb, void *data,
|
||||||
struct mg_resolve_async_opts opts) {
|
struct mg_resolve_async_opts opts) {
|
||||||
struct mg_resolve_async_request *req;
|
struct mg_resolve_async_request *req;
|
||||||
struct mg_connection *dmg_nc;
|
struct mg_connection *dns_nc;
|
||||||
const char *nameserver = opts.nameserver_url;
|
const char *nameserver = opts.nameserver_url;
|
||||||
|
|
||||||
DBG(("%s %d", name, query));
|
DBG(("%s %d", name, query));
|
||||||
@ -7546,22 +7546,22 @@ int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,
|
|||||||
req->timeout = opts.timeout ? opts.timeout : 5;
|
req->timeout = opts.timeout ? opts.timeout : 5;
|
||||||
|
|
||||||
/* Lazily initialize dns server */
|
/* Lazily initialize dns server */
|
||||||
if (nameserver == NULL && mg_dmg_server[0] == '\0' &&
|
if (nameserver == NULL && mg_dns_server[0] == '\0' &&
|
||||||
mg_get_ip_address_of_nameserver(mg_dmg_server, sizeof(mg_dmg_server)) ==
|
mg_get_ip_address_of_nameserver(mg_dns_server, sizeof(mg_dns_server)) ==
|
||||||
-1) {
|
-1) {
|
||||||
strncpy(mg_dmg_server, mg_default_dmg_server, sizeof(mg_dmg_server));
|
strncpy(mg_dns_server, mg_default_dns_server, sizeof(mg_dns_server));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nameserver == NULL) {
|
if (nameserver == NULL) {
|
||||||
nameserver = mg_dmg_server;
|
nameserver = mg_dns_server;
|
||||||
}
|
}
|
||||||
|
|
||||||
dmg_nc = mg_connect(mgr, nameserver, mg_resolve_async_eh);
|
dns_nc = mg_connect(mgr, nameserver, mg_resolve_async_eh);
|
||||||
if (dmg_nc == NULL) {
|
if (dns_nc == NULL) {
|
||||||
free(req);
|
free(req);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
dmg_nc->user_data = req;
|
dns_nc->user_data = req;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
66
mongoose.h
66
mongoose.h
@ -2139,35 +2139,35 @@ extern "C" {
|
|||||||
|
|
||||||
#define MG_DNS_MESSAGE 100 /* High-level DNS message event */
|
#define MG_DNS_MESSAGE 100 /* High-level DNS message event */
|
||||||
|
|
||||||
enum mg_dmg_resource_record_kind {
|
enum mg_dns_resource_record_kind {
|
||||||
MG_DNS_INVALID_RECORD = 0,
|
MG_DNS_INVALID_RECORD = 0,
|
||||||
MG_DNS_QUESTION,
|
MG_DNS_QUESTION,
|
||||||
MG_DNS_ANSWER
|
MG_DNS_ANSWER
|
||||||
};
|
};
|
||||||
|
|
||||||
/* DNS resource record. */
|
/* DNS resource record. */
|
||||||
struct mg_dmg_resource_record {
|
struct mg_dns_resource_record {
|
||||||
struct mg_str name; /* buffer with compressed name */
|
struct mg_str name; /* buffer with compressed name */
|
||||||
int rtype;
|
int rtype;
|
||||||
int rclass;
|
int rclass;
|
||||||
int ttl;
|
int ttl;
|
||||||
enum mg_dmg_resource_record_kind kind;
|
enum mg_dns_resource_record_kind kind;
|
||||||
struct mg_str rdata; /* protocol data (can be a compressed name) */
|
struct mg_str rdata; /* protocol data (can be a compressed name) */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* DNS message (request and response). */
|
/* DNS message (request and response). */
|
||||||
struct mg_dmg_message {
|
struct mg_dns_message {
|
||||||
struct mg_str pkt; /* packet body */
|
struct mg_str pkt; /* packet body */
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
uint16_t transaction_id;
|
uint16_t transaction_id;
|
||||||
int num_questions;
|
int num_questions;
|
||||||
int num_answers;
|
int num_answers;
|
||||||
struct mg_dmg_resource_record questions[MG_MAX_DNS_QUESTIONS];
|
struct mg_dns_resource_record questions[MG_MAX_DNS_QUESTIONS];
|
||||||
struct mg_dmg_resource_record answers[MG_MAX_DNS_ANSWERS];
|
struct mg_dns_resource_record answers[MG_MAX_DNS_ANSWERS];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mg_dmg_resource_record *mg_dmg_next_record(
|
struct mg_dns_resource_record *mg_dns_next_record(
|
||||||
struct mg_dmg_message *, int, struct mg_dmg_resource_record *);
|
struct mg_dns_message *, int, struct mg_dns_resource_record *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the record data from a DNS resource record.
|
* Parse the record data from a DNS resource record.
|
||||||
@ -2180,20 +2180,20 @@ struct mg_dmg_resource_record *mg_dmg_next_record(
|
|||||||
*
|
*
|
||||||
* TODO(mkm): MX
|
* TODO(mkm): MX
|
||||||
*/
|
*/
|
||||||
int mg_dmg_parse_record_data(struct mg_dmg_message *,
|
int mg_dns_parse_record_data(struct mg_dns_message *,
|
||||||
struct mg_dmg_resource_record *, void *, size_t);
|
struct mg_dns_resource_record *, void *, size_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send a DNS query to the remote end.
|
* Send a DNS query to the remote end.
|
||||||
*/
|
*/
|
||||||
void mg_send_dmg_query(struct mg_connection *, const char *, int);
|
void mg_send_dns_query(struct mg_connection *, const char *, int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a DNS header to an IO buffer.
|
* Insert a DNS header to an IO buffer.
|
||||||
*
|
*
|
||||||
* Return number of bytes inserted.
|
* Return number of bytes inserted.
|
||||||
*/
|
*/
|
||||||
int mg_dmg_insert_header(struct mbuf *, size_t, struct mg_dmg_message *);
|
int mg_dns_insert_header(struct mbuf *, size_t, struct mg_dns_message *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Append already encoded body from an existing message.
|
* Append already encoded body from an existing message.
|
||||||
@ -2203,7 +2203,7 @@ int mg_dmg_insert_header(struct mbuf *, size_t, struct mg_dmg_message *);
|
|||||||
*
|
*
|
||||||
* Return number of appened bytes.
|
* Return number of appened bytes.
|
||||||
*/
|
*/
|
||||||
int mg_dmg_copy_body(struct mbuf *, struct mg_dmg_message *);
|
int mg_dns_copy_body(struct mbuf *, struct mg_dns_message *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encode and append a DNS resource record to an IO buffer.
|
* Encode and append a DNS resource record to an IO buffer.
|
||||||
@ -2221,11 +2221,11 @@ int mg_dmg_copy_body(struct mbuf *, struct mg_dmg_message *);
|
|||||||
*
|
*
|
||||||
* Return the number of bytes appened or -1 in case of error.
|
* Return the number of bytes appened or -1 in case of error.
|
||||||
*/
|
*/
|
||||||
int mg_dmg_encode_record(struct mbuf *, struct mg_dmg_resource_record *,
|
int mg_dns_encode_record(struct mbuf *, struct mg_dns_resource_record *,
|
||||||
const char *, size_t, const void *, size_t);
|
const char *, size_t, const void *, size_t);
|
||||||
|
|
||||||
/* Low-level: parses a DNS response. */
|
/* Low-level: parses a DNS response. */
|
||||||
int mg_parse_dns(const char *, int, struct mg_dmg_message *);
|
int mg_parse_dns(const char *, int, struct mg_dns_message *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Uncompress a DNS compressed name.
|
* Uncompress a DNS compressed name.
|
||||||
@ -2240,7 +2240,7 @@ int mg_parse_dns(const char *, int, struct mg_dmg_message *);
|
|||||||
* If `dst_len` is 0 `dst` can be NULL.
|
* If `dst_len` is 0 `dst` can be NULL.
|
||||||
* Return the uncompressed name length.
|
* Return the uncompressed name length.
|
||||||
*/
|
*/
|
||||||
size_t mg_dmg_uncompress_name(struct mg_dmg_message *, struct mg_str *, char *,
|
size_t mg_dns_uncompress_name(struct mg_dns_message *, struct mg_str *, char *,
|
||||||
int);
|
int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2249,10 +2249,10 @@ size_t mg_dmg_uncompress_name(struct mg_dmg_message *, struct mg_str *, char *,
|
|||||||
* DNS event handler parses incoming UDP packets, treating them as DNS
|
* DNS event handler parses incoming UDP packets, treating them as DNS
|
||||||
* requests. If incoming packet gets successfully parsed by the DNS event
|
* requests. If incoming packet gets successfully parsed by the DNS event
|
||||||
* handler, a user event handler will receive `MG_DNS_REQUEST` event, with
|
* handler, a user event handler will receive `MG_DNS_REQUEST` event, with
|
||||||
* `ev_data` pointing to the parsed `struct mg_dmg_message`.
|
* `ev_data` pointing to the parsed `struct mg_dns_message`.
|
||||||
*
|
*
|
||||||
* See
|
* See
|
||||||
* https://github.com/cesanta/mongoose/tree/master/examples/captive_dmg_server[captive_dmg_server]
|
* https://github.com/cesanta/mongoose/tree/master/examples/captive_dns_server[captive_dns_server]
|
||||||
* example on how to handle DNS request and send DNS reply.
|
* example on how to handle DNS request and send DNS reply.
|
||||||
*/
|
*/
|
||||||
void mg_set_protocol_dns(struct mg_connection *);
|
void mg_set_protocol_dns(struct mg_connection *);
|
||||||
@ -2284,8 +2284,8 @@ extern "C" {
|
|||||||
|
|
||||||
#define MG_DNS_SERVER_DEFAULT_TTL 3600
|
#define MG_DNS_SERVER_DEFAULT_TTL 3600
|
||||||
|
|
||||||
struct mg_dmg_reply {
|
struct mg_dns_reply {
|
||||||
struct mg_dmg_message *msg;
|
struct mg_dns_message *msg;
|
||||||
struct mbuf *io;
|
struct mbuf *io;
|
||||||
size_t start;
|
size_t start;
|
||||||
};
|
};
|
||||||
@ -2298,10 +2298,10 @@ struct mg_dmg_reply {
|
|||||||
* "reply + recursion allowed" will be added to the message flags and
|
* "reply + recursion allowed" will be added to the message flags and
|
||||||
* message's num_answers will be set to 0.
|
* message's num_answers will be set to 0.
|
||||||
*
|
*
|
||||||
* Answer records can be appended with `mg_dmg_send_reply` or by lower
|
* Answer records can be appended with `mg_dns_send_reply` or by lower
|
||||||
* level function defined in the DNS API.
|
* level function defined in the DNS API.
|
||||||
*
|
*
|
||||||
* In order to send the reply use `mg_dmg_send_reply`.
|
* In order to send the reply use `mg_dns_send_reply`.
|
||||||
* It's possible to use a connection's send buffer as reply buffers,
|
* It's possible to use a connection's send buffer as reply buffers,
|
||||||
* and it will work for both UDP and TCP connections.
|
* and it will work for both UDP and TCP connections.
|
||||||
*
|
*
|
||||||
@ -2309,17 +2309,17 @@ struct mg_dmg_reply {
|
|||||||
*
|
*
|
||||||
* [source,c]
|
* [source,c]
|
||||||
* -----
|
* -----
|
||||||
* reply = mg_dmg_create_reply(&nc->send_mbuf, msg);
|
* reply = mg_dns_create_reply(&nc->send_mbuf, msg);
|
||||||
* for (i = 0; i < msg->num_questions; i++) {
|
* for (i = 0; i < msg->num_questions; i++) {
|
||||||
* rr = &msg->questions[i];
|
* rr = &msg->questions[i];
|
||||||
* if (rr->rtype == MG_DNS_A_RECORD) {
|
* if (rr->rtype == MG_DNS_A_RECORD) {
|
||||||
* mg_dmg_reply_record(&reply, rr, 3600, &dummy_ip_addr, 4);
|
* mg_dns_reply_record(&reply, rr, 3600, &dummy_ip_addr, 4);
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* mg_dmg_send_reply(nc, &reply);
|
* mg_dns_send_reply(nc, &reply);
|
||||||
* -----
|
* -----
|
||||||
*/
|
*/
|
||||||
struct mg_dmg_reply mg_dmg_create_reply(struct mbuf *, struct mg_dmg_message *);
|
struct mg_dns_reply mg_dns_create_reply(struct mbuf *, struct mg_dns_message *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Append a DNS reply record to the IO buffer and to the DNS message.
|
* Append a DNS reply record to the IO buffer and to the DNS message.
|
||||||
@ -2329,7 +2329,7 @@ struct mg_dmg_reply mg_dmg_create_reply(struct mbuf *, struct mg_dmg_message *);
|
|||||||
*
|
*
|
||||||
* Returns -1 on error.
|
* Returns -1 on error.
|
||||||
*/
|
*/
|
||||||
int mg_dmg_reply_record(struct mg_dmg_reply *, struct mg_dmg_resource_record *,
|
int mg_dns_reply_record(struct mg_dns_reply *, struct mg_dns_resource_record *,
|
||||||
const char *, int, int, const void *, size_t);
|
const char *, int, int, const void *, size_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2338,13 +2338,13 @@ int mg_dmg_reply_record(struct mg_dmg_reply *, struct mg_dmg_resource_record *,
|
|||||||
* The DNS data is stored in an IO buffer pointed by reply structure in `r`.
|
* The DNS data is stored in an IO buffer pointed by reply structure in `r`.
|
||||||
* This function mutates the content of that buffer in order to ensure that
|
* This function mutates the content of that buffer in order to ensure that
|
||||||
* the DNS header reflects size and flags of the mssage, that might have been
|
* the DNS header reflects size and flags of the mssage, that might have been
|
||||||
* updated either with `mg_dmg_reply_record` or by direct manipulation of
|
* updated either with `mg_dns_reply_record` or by direct manipulation of
|
||||||
* `r->message`.
|
* `r->message`.
|
||||||
*
|
*
|
||||||
* Once sent, the IO buffer will be trimmed unless the reply IO buffer
|
* Once sent, the IO buffer will be trimmed unless the reply IO buffer
|
||||||
* is the connection's send buffer and the connection is not in UDP mode.
|
* is the connection's send buffer and the connection is not in UDP mode.
|
||||||
*/
|
*/
|
||||||
int mg_dmg_send_reply(struct mg_connection *, struct mg_dmg_reply *);
|
int mg_dns_send_reply(struct mg_connection *, struct mg_dns_reply *);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
@ -2369,7 +2369,7 @@ int mg_dmg_send_reply(struct mg_connection *, struct mg_dmg_reply *);
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
typedef void (*mg_resolve_callback_t)(struct mg_dmg_message *, void *);
|
typedef void (*mg_resolve_callback_t)(struct mg_dns_message *, void *);
|
||||||
|
|
||||||
/* Options for `mg_resolve_async_opt`. */
|
/* Options for `mg_resolve_async_opt`. */
|
||||||
struct mg_resolve_async_opts {
|
struct mg_resolve_async_opts {
|
||||||
@ -2395,14 +2395,14 @@ int mg_resolve_async(struct mg_mgr *, const char *, int, mg_resolve_callback_t,
|
|||||||
* will receive a NULL `msg`.
|
* will receive a NULL `msg`.
|
||||||
*
|
*
|
||||||
* The DNS answers can be extracted with `mg_next_record` and
|
* The DNS answers can be extracted with `mg_next_record` and
|
||||||
* `mg_dmg_parse_record_data`:
|
* `mg_dns_parse_record_data`:
|
||||||
*
|
*
|
||||||
* [source,c]
|
* [source,c]
|
||||||
* ----
|
* ----
|
||||||
* struct in_addr ina;
|
* struct in_addr ina;
|
||||||
* struct mg_dmg_resource_record *rr = mg_next_record(msg, MG_DNS_A_RECORD,
|
* struct mg_dns_resource_record *rr = mg_next_record(msg, MG_DNS_A_RECORD,
|
||||||
* NULL);
|
* NULL);
|
||||||
* mg_dmg_parse_record_data(msg, rr, &ina, sizeof(ina));
|
* mg_dns_parse_record_data(msg, rr, &ina, sizeof(ina));
|
||||||
* ----
|
* ----
|
||||||
*/
|
*/
|
||||||
int mg_resolve_async_opt(struct mg_mgr *, const char *, int,
|
int mg_resolve_async_opt(struct mg_mgr *, const char *, int,
|
||||||
|
Loading…
Reference in New Issue
Block a user