Skip to content

Commit

Permalink
For #6 - update dns to use esp rng, although it's not using the new e…
Browse files Browse the repository at this point in the history
…ntropy pool yet. Add some debugging use of the entropy pool. Optimize a little using flash attributes.
  • Loading branch information
eastein committed Jan 30, 2016
1 parent 1d9a47c commit c12cc09
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 31 deletions.
5 changes: 5 additions & 0 deletions user/bkmacros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#ifdef INTEST
#define BK_CACHEABLE
#else
#define BK_CACHEABLE ICACHE_FLASH_ATTR
#endif
27 changes: 16 additions & 11 deletions user/dns.h
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
#ifndef BK_DNS_H
#define BK_DNS_H 1

#include "bkmacros.h"

#include "c_types.h"
#include "user_interface.h"
#include "ip_addr.h"
#include "espconn.h"
#include "debugging.h"
#include "bk_rng.h"

bool bkdns_udp_setup = false;
struct espconn bkdns_udp_conn;
esp_udp bkdns_net_udp;
uint16_t seq;


void dns_response_callback(void *arg, char *pdata, unsigned short len);

void bk_dns_init(unsigned char dnsnum) {
void BK_CACHEABLE bk_dns_init(unsigned char dnsnum) {
if (bkdns_udp_setup) {
return;
}

seq = 27; // it would be good to do seq number randomization, gonna get owned XXX FIXME

ip_addr_t ipa;
ipa = dns_getserver(dnsnum);
Expand All @@ -36,6 +37,7 @@ void bk_dns_init(unsigned char dnsnum) {
bkdns_udp_conn.recv_callback = dns_response_callback;
DEBUGUART("DNS Source Port: %d Target Port: %d\r\n", bkdns_udp_conn.proto.udp->local_port, bkdns_udp_conn.proto.udp->remote_port);
os_memcpy(bkdns_udp_conn.proto.udp->remote_ip, &ip, 4);

if (espconn_create(&bkdns_udp_conn) == ESPCONN_OK) {
bkdns_udp_setup = true;
} else {
Expand Down Expand Up @@ -120,14 +122,14 @@ PACK_STRUCT_END

#include "dns_util.h"

inline void write_uint16(char* buf, uint16_t v) {
inline void write_uint16(char *buf, uint16_t v) {
// alignment for 16 bit is 2 bytes, so we can't treat it that way unless we're lucky to be on
// an aligned access
uint16_t tmp16 = LWIP_PLATFORM_HTONS(v);
os_memcpy(buf, (char*)(&tmp16), 2);
os_memcpy(buf, (char *)(&tmp16), 2);
}

void bk_dns_query(uint8_t numdns, char* name) {
void BK_CACHEABLE bk_dns_query(uint8_t numdns, char *name) {
/*
TODO make this smart enough to allow multiple pending DNS queries, and actually parse
the response fully, plus support more than just SRV...
Expand All @@ -138,24 +140,26 @@ void bk_dns_query(uint8_t numdns, char* name) {

// 18 bytes for header + question + other overhead, 256 bytes for name queried
char sendbuf[274];
char* sendbuf_ptr = (char*)(&sendbuf);
char *sendbuf_ptr = (char *)(&sendbuf);

os_memset(sendbuf, 0, 274);

uint16_t seq = (uint16_t)esp_hardware_rng();

// dns header - flags2 can be left alone and we are just doing 1 question
write_uint16(sendbuf_ptr + DHO_ID, seq);
*((uint8_t*)(&(sendbuf[DHO_FL1]))) = DNS_FLAG1_RD;
*((uint8_t *)(&(sendbuf[DHO_FL1]))) = DNS_FLAG1_RD;
write_uint16(sendbuf_ptr + DHO_NQST, 1);

size_t bytes_used = 12;

// name parameter
bytes_used += hostname_to_queryformat(name, &(sendbuf[bytes_used]));
bytes_used += bk_hostname_to_queryformat(name, &(sendbuf[bytes_used]));

DEBUGUART("bk_dns_query: wrote hostname to query. bytes_used=%d\r\n", bytes_used);

// query options
sendbuf_ptr = (char*) &(sendbuf[bytes_used]);
sendbuf_ptr = (char *) &(sendbuf[bytes_used]);
write_uint16(sendbuf_ptr, DNS_RRTYPE_SRV);
write_uint16(sendbuf_ptr + 2, DNS_RRCLASS_IN);
bytes_used += 4;
Expand All @@ -165,6 +169,7 @@ void bk_dns_query(uint8_t numdns, char* name) {
print_hexdump(sendbuf, bytes_used);

char ret = espconn_sent(&bkdns_udp_conn, sendbuf, bytes_used);

if (ret != ESPCONN_OK) {
uart0_sendStr("bk_dns_query: Error Sending DNS query Packet...\r\n");
} else {
Expand All @@ -173,7 +178,7 @@ void bk_dns_query(uint8_t numdns, char* name) {
}


void dns_response_callback(void *arg, char *pdata, unsigned short len) {
void BK_CACHEABLE dns_response_callback(void *arg, char *pdata, unsigned short len) {
DEBUGUART("%s", "UDP response:\r\n");
print_hexdump(pdata, len);
}
Expand Down
58 changes: 41 additions & 17 deletions user/dns_util.h
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
#ifndef BK_DNS_UTIL_H
#define BK_DNS_UTIL_H 1

#include "bkmacros.h"

inline unsigned char casefold(unsigned char c) {
// subtract 0x20 from all octets in the inclusive range from 0x61 to 0x7A before comparing

if ((c >= 0x61) && (c <= 0x7a)) {
return c - 0x20;
}

return c;
}

inline
uint8_t
compare_chars(unsigned char a, unsigned char b) {
inline uint8_t compare_chars(unsigned char a, unsigned char b) {
if (casefold(a) == casefold(b)) {
return 0;
} else {
Expand All @@ -21,14 +22,14 @@ compare_chars(unsigned char a, unsigned char b) {
}

// mostly taken from lwip core/dns.c, with modifications
size_t hostname_to_queryformat(char* name, char* query) {
size_t BK_CACHEABLE bk_hostname_to_queryformat(char *name, char *query) {
/*
@param name char pointer to the start of a c string of the name to convert into query format and copy into the query buffer
@param query pointer to location where the query formatted version of the name should be written to
@returns number of bytes used in the query buffer by encoding the name
*/
uint8_t n;
char* nptr;
char *nptr;
size_t bytes_used = 0;
name--;

Expand All @@ -38,15 +39,18 @@ size_t hostname_to_queryformat(char* name, char* query) {
nptr = query;
++query;
bytes_used++; // nptr points to where the length will be stored. we have 'used' that.

for(n = 0; *name != '.' && *name != 0; ++name) {
*query = *name;
bytes_used++; // we used a byte to store a byte of the name
++query;
++n;
}

// we write back to the start (it's length prefix encoded, unsigned 8 bit int)
*nptr = n;
} while(*name != 0);

// write a 0 over the end, and then increment the query pointer
// this means we're using another byte, I guess... but isn't the *nptr = n line already doing this?

Expand All @@ -58,23 +62,22 @@ size_t hostname_to_queryformat(char* name, char* query) {
return bytes_used;
}

// from lwip
// from lwip, with modifications to support name compression
/**
* Compare the "dotted" name "query" with the encoded name "response"
*
* @param query hostname (not encoded) from the dns_table
* @param response_ptr pointer to the start of the DNS response
* @param response_size number of bytes in the dns response packet, used to ensure we don't read outside
* @param msg_ptr pointer to the start of the DNS response
* @param msg_size number of bytes in the dns response packet, used to ensure we don't read outside
the response message
* @param offset offset of the encoded hostname in the DNS response. Assumed to be less than response_size
* @param offset offset of the encoded hostname in the DNS response. Assumed to be less than msg_size
* @return 0: names equal; 1: names differ
*/
static uint8_t
dns_compare_name(unsigned char *query, unsigned char *response_ptr, uint16_t response_size, uint16_t offset)
{
static uint8_t BK_CACHEABLE
bkdns_compare_name(unsigned char *query, unsigned char *msg_ptr, uint16_t msg_size, uint16_t offset) {
unsigned char n;
unsigned char* response = response_ptr;
unsigned char* end = response_ptr + response_size;
unsigned char *response = msg_ptr;
unsigned char *end = msg_ptr + msg_size;
//response += offset;
uint8_t compression_jumped = 1;

Expand All @@ -83,12 +86,13 @@ dns_compare_name(unsigned char *query, unsigned char *response_ptr, uint16_t res
do {
// how many bytes and/or
n = response[offset++];

//printf("n = %d\n", n);
if ((n & 0xc0) == 0xc0) {
/** @see RFC 1035 - 4.1.4. Message compression */
/* Compressed name */

if ((offset >= response_size) || (offset == 0)) {
if ((offset >= msg_size) || (offset == 0)) {
//printf("<<<<<<<< pointer out of range (offset=%d). No match.\n", offset);
return 1;
}
Expand All @@ -97,10 +101,12 @@ dns_compare_name(unsigned char *query, unsigned char *response_ptr, uint16_t res
//printf("<<<<<< you can only do one compression jump per name.\n");
return 1;
}

compression_jumped = 0;

uint16_t current_offset = offset - 1;
offset = 255 * (0xc0 ^ n) + response[offset++];

//printf("found offset to be %d after decoding pointer.\n", n);
if (offset >= current_offset) {
//printf("<<<<<<< forward pointers disallowed. No match. current offset=%d, jump=%d\n", current_offset, offset);
Expand All @@ -109,22 +115,25 @@ dns_compare_name(unsigned char *query, unsigned char *response_ptr, uint16_t res
} else {
/* Not compressed name */
while (n > 0) {
if (offset >= response_size) {
if (offset >= msg_size) {
//printf("<<<<<< offset has grown larger than size of response. no match.\n");
return 1;
}

if (compare_chars(*query, response[offset]) != 0) {
//printf("<<<<<< a byte did not match. no match! Char in response was %c, in query was %c\n", response[offset], *query);
return 1;
}

//printf("a byte did match.. %c\n", *query);
++offset;
++query;
--n;
};

++query;

if (offset >= response_size) {
if (offset >= msg_size) {
//printf("<<<<<< offset has grown larger than size of response. no match.\n");
return 1;
}
Expand All @@ -135,6 +144,21 @@ dns_compare_name(unsigned char *query, unsigned char *response_ptr, uint16_t res
//printf("<<<<<< reached end. match!\n");
return 0;
}
/*
* @param name buffer of size DNS_MAX_NAME_LENGTH to write the result to.
* @param msg_ptr pointer to the start of the DNS message
* @param msg_size number of bytes in the dns message packet, used to ensure we don't read outside
the response message
* @param offset offset of the encoded hostname in the DNS response. Assumed to be less than msg_size
* @return 0: successfully parsed msg formatted name and wrote in hostname format into name parameter; 1: malformed
name could not be parsed successfully but name parameter's buffer may have been partially updated and
should not be used.
*/
static uint8_t BK_CACHEABLE
bkdns_msgformat_to_hostname(unsigned char *query, unsigned char *msg_ptr, uint16_t msg_size, uint16_t offset) {
// TODO implement me
return 1;
}


#endif
31 changes: 28 additions & 3 deletions user/user_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "dns.h"
#include "debugging.h"

#include "bk_rng.h"

#define user_procTaskPrio 0
#define user_procTaskQueueLen 1
os_event_t user_procTaskQueue[user_procTaskQueueLen];
Expand Down Expand Up @@ -152,13 +154,11 @@ void ICACHE_FLASH_ATTR udp_connect_maybe() {
return;

// looking up the SRV record

/*
char name[255];
os_sprintf(name, "_thingsbus_input._udp.%s", TBB_ZONE);
DEBUGUART("Query SRV %s\r\n", name);
bk_dns_query(0, name);
*/


char temp[23];
unsigned long ip = 0;
Expand Down Expand Up @@ -465,6 +465,31 @@ void ICACHE_FLASH_ATTR
user_init()
{
uart_init(115200, 115200);

/*
uart0_sendStr("\r\n4096 random bytes, as hex:\r\n");
int i, j;
for (i = 0; i < 64; i++) {
for (j = 0; j < 16; j++) {
DEBUGUART("%08x", esp_hardware_rng());
}
uart0_sendStr("\r\n");
}
uart0_sendStr("\r\nend of random bytes.\r\n");
*/

struct bk_rng_state rng_state;
bk_rng_init(&rng_state);

uart0_sendStr("\r\n32 random bytes, as hex:\r\n");
int i;

for (i = 0; i < 32; i++) {
DEBUGUART("%02x\r\n", bk_rng_8bit(&rng_state));
}

uart0_sendStr("\r\nend of random bytes.\r\n");

wifi_init();

uart0_sendStr("\r\n[boot] Wi-Fi initialized\r\n");
Expand Down

0 comments on commit c12cc09

Please sign in to comment.