Skip to content

Commit 3e4de76

Browse files
authored
Merge branch 'master' into thunks
2 parents 5583696 + 464bdcc commit 3e4de76

File tree

30 files changed

+944
-243
lines changed

30 files changed

+944
-243
lines changed

README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ ESP8266 Arduino core comes with libraries to communicate over WiFi using TCP and
88
# Contents
99
- Installing options:
1010
- [Using Boards Manager](#installing-with-boards-manager)
11-
- [Using git version](#using-git-version)
11+
- [Using git version](#using-git-version-basic-instructions)
1212
- [Using PlatformIO](#using-platformio)
1313
- [Building with make](#building-with-make)
1414
- [Documentation](#documentation)
@@ -30,15 +30,19 @@ Boards manager link: `http://arduino.esp8266.com/stable/package_esp8266com_index
3030

3131
Documentation: [https://arduino-esp8266.readthedocs.io/en/2.4.2/](https://arduino-esp8266.readthedocs.io/en/2.4.2/)
3232

33-
### Using git version
33+
### Using git version (basic instructions)
3434
[![Linux build status](https://travis-ci.org/esp8266/Arduino.svg)](https://travis-ci.org/esp8266/Arduino)
3535

3636
- Install the current upstream Arduino IDE at the 1.8 level or later. The current version is at the [Arduino website](http://www.arduino.cc/en/main/software).
37-
- Go to Arduino application directory
37+
- Go to Arduino directory
3838
- For Mac OS X, it is `Arduino.app` showing as the Arduino icon.
3939
This location may be your `~/Downloads`, `~/Desktop` or even `/Applications`.
4040
```bash
41-
cd <application-directory>/Arduino.app/Contents/
41+
cd <application-directory>/Arduino.app/Contents/Java
42+
```
43+
- For Linux, it is ~/arduino by default.
44+
```bash
45+
cd ~arduino
4246
```
4347
- Clone this repository into hardware/esp8266com/esp8266 directory (or clone it elsewhere and create a symlink)
4448
```bash
@@ -124,3 +128,5 @@ ESP8266 core files are licensed under LGPL.
124128
[umm_malloc](https://github.com/rhempel/umm_malloc) memory management library written by Ralph Hempel is used in this project. It is distributed under MIT license.
125129

126130
[axTLS](http://axtls.sourceforge.net/) library written by Cameron Rich, built from https://github.com/igrr/axtls-8266, is used in this project. It is distributed under [BSD license](https://github.com/igrr/axtls-8266/blob/master/LICENSE).
131+
132+
[BearSSL](https://bearssl.org) library written by Thomas Pornin, built from https://github.com/earlephilhower/bearssl-esp8266, is used in this project. It is distributed under the [MIT License](https://bearssl.org/#legal-details).

cores/esp8266/Updater.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,26 @@ void UpdaterClass::_reset() {
3535
_currentAddress = 0;
3636
_size = 0;
3737
_command = U_FLASH;
38+
39+
if(_ledPin != -1) {
40+
digitalWrite(_ledPin, _ledStateRestore);
41+
}
3842
}
3943

40-
bool UpdaterClass::begin(size_t size, int command) {
44+
bool UpdaterClass::begin(size_t size, int command, int ledPin, uint8_t ledOn) {
4145
if(_size > 0){
4246
#ifdef DEBUG_UPDATER
4347
DEBUG_UPDATER.println(F("[begin] already running"));
4448
#endif
4549
return false;
4650
}
4751

52+
_ledPin = ledPin;
53+
_ledOn = ledOn;
54+
if(_ledPin != -1) {
55+
_ledStateRestore = digitalRead(_ledPin);
56+
}
57+
4858
/* Check boot mode; if boot mode is 1 (UART download mode),
4959
we will not be able to reset into normal mode once update is done.
5060
Fail early to avoid frustration.
@@ -360,18 +370,32 @@ size_t UpdaterClass::writeStream(Stream &data) {
360370
return 0;
361371
}
362372

373+
if(_ledPin != -1) {
374+
pinMode(_ledPin, OUTPUT);
375+
}
376+
363377
while(remaining()) {
364-
toRead = data.readBytes(_buffer + _bufferLen, (_bufferSize - _bufferLen));
378+
if(_ledPin != -1) {
379+
digitalWrite(LED_BUILTIN, _ledOn); // Switch LED on
380+
}
381+
size_t bytesToRead = _bufferSize - _bufferLen;
382+
if(bytesToRead > remaining()) {
383+
bytesToRead = remaining();
384+
}
385+
toRead = data.readBytes(_buffer + _bufferLen, bytesToRead);
365386
if(toRead == 0) { //Timeout
366387
delay(100);
367-
toRead = data.readBytes(_buffer + _bufferLen, (_bufferSize - _bufferLen));
388+
toRead = data.readBytes(_buffer + _bufferLen, bytesToRead);
368389
if(toRead == 0) { //Timeout
369390
_currentAddress = (_startAddress + _size);
370391
_setError(UPDATE_ERROR_STREAM);
371392
_reset();
372393
return written;
373394
}
374395
}
396+
if(_ledPin != -1) {
397+
digitalWrite(LED_BUILTIN, _ledOn == HIGH ? LOW : HIGH); // Switch LED off
398+
}
375399
_bufferLen += toRead;
376400
if((_bufferLen == remaining() || _bufferLen == _bufferSize) && !_writeBuffer())
377401
return written;

cores/esp8266/Updater.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class UpdaterClass {
3535
Call this to check the space needed for the update
3636
Will return false if there is not enough space
3737
*/
38-
bool begin(size_t size, int command = U_FLASH);
38+
bool begin(size_t size, int command = U_FLASH, int ledPin = -1, uint8_t ledOn = LOW);
3939

4040
/*
4141
Run Updater from asynchronous callbacs
@@ -162,6 +162,10 @@ class UpdaterClass {
162162

163163
String _target_md5;
164164
MD5Builder _md5;
165+
166+
int _ledPin;
167+
uint8_t _ledOn;
168+
int _ledStateRestore;
165169
};
166170

167171
extern UpdaterClass Update;

libraries/DNSServer/keywords.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ stop KEYWORD2
3333
DNS_QR_QUERY LITERAL1 RESERVED_WORD_2
3434
DNS_QR_RESPONSE LITERAL1 RESERVED_WORD_2
3535
DNS_OPCODE_QUERY LITERAL1 RESERVED_WORD_2
36+
MAX_DNSNAME_LENGTH LITERAL1 RESERVED_WORD_2
3637
NoError LITERAL1 RESERVED_WORD_2
3738
FormError LITERAL1 RESERVED_WORD_2
3839
ServerFailure LITERAL1 RESERVED_WORD_2

libraries/DNSServer/library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=DNSServer
2-
version=1.1.0
2+
version=1.1.1
33
author=Kristijan Novoselić
44
maintainer=Kristijan Novoselić, <[email protected]>
55
sentence=A simple DNS server for ESP8266.

libraries/DNSServer/src/DNSServer.cpp

Lines changed: 85 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ bool DNSServer::start(const uint16_t &port, const String &domainName,
1313
const IPAddress &resolvedIP)
1414
{
1515
_port = port;
16-
_buffer = NULL;
16+
1717
_domainName = domainName;
1818
_resolvedIP[0] = resolvedIP[0];
1919
_resolvedIP[1] = resolvedIP[1];
@@ -36,8 +36,6 @@ void DNSServer::setTTL(const uint32_t &ttl)
3636
void DNSServer::stop()
3737
{
3838
_udp.stop();
39-
free(_buffer);
40-
_buffer = NULL;
4139
}
4240

4341
void DNSServer::downcaseAndRemoveWwwPrefix(String &domainName)
@@ -48,82 +46,106 @@ void DNSServer::downcaseAndRemoveWwwPrefix(String &domainName)
4846

4947
void DNSServer::processNextRequest()
5048
{
51-
_currentPacketSize = _udp.parsePacket();
52-
if (_currentPacketSize)
49+
size_t packetSize = _udp.parsePacket();
50+
51+
if (packetSize >= sizeof(DNSHeader))
5352
{
54-
if (_buffer != NULL) free(_buffer);
55-
_buffer = (unsigned char*)malloc(_currentPacketSize * sizeof(char));
56-
if (_buffer == NULL) return;
57-
_udp.read(_buffer, _currentPacketSize);
58-
_dnsHeader = (DNSHeader*) _buffer;
59-
60-
if (_dnsHeader->QR == DNS_QR_QUERY &&
61-
_dnsHeader->OPCode == DNS_OPCODE_QUERY &&
62-
requestIncludesOnlyOneQuestion() &&
63-
(_domainName == "*" || getDomainNameWithoutWwwPrefix() == _domainName)
53+
uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(packetSize));
54+
if (buffer == NULL) return;
55+
56+
_udp.read(buffer, packetSize);
57+
58+
DNSHeader* dnsHeader = reinterpret_cast<DNSHeader*>(buffer);
59+
60+
if (dnsHeader->QR == DNS_QR_QUERY &&
61+
dnsHeader->OPCode == DNS_OPCODE_QUERY &&
62+
requestIncludesOnlyOneQuestion(dnsHeader) &&
63+
(_domainName == "*" || getDomainNameWithoutWwwPrefix(buffer, packetSize) == _domainName)
6464
)
6565
{
66-
replyWithIP();
66+
replyWithIP(buffer, packetSize);
6767
}
68-
else if (_dnsHeader->QR == DNS_QR_QUERY)
68+
else if (dnsHeader->QR == DNS_QR_QUERY)
6969
{
70-
replyWithCustomCode();
70+
replyWithCustomCode(buffer, packetSize);
7171
}
7272

73-
free(_buffer);
74-
_buffer = NULL;
73+
free(buffer);
7574
}
7675
}
7776

78-
bool DNSServer::requestIncludesOnlyOneQuestion()
77+
bool DNSServer::requestIncludesOnlyOneQuestion(const DNSHeader* dnsHeader)
7978
{
80-
return ntohs(_dnsHeader->QDCount) == 1 &&
81-
_dnsHeader->ANCount == 0 &&
82-
_dnsHeader->NSCount == 0 &&
83-
_dnsHeader->ARCount == 0;
79+
return ntohs(dnsHeader->QDCount) == 1 &&
80+
dnsHeader->ANCount == 0 &&
81+
dnsHeader->NSCount == 0 &&
82+
dnsHeader->ARCount == 0;
8483
}
8584

86-
String DNSServer::getDomainNameWithoutWwwPrefix()
85+
String DNSServer::getDomainNameWithoutWwwPrefix(const uint8_t* buffer, size_t packetSize)
8786
{
88-
String parsedDomainName = "";
89-
if (_buffer == NULL) return parsedDomainName;
90-
unsigned char *start = _buffer + 12;
91-
if (*start == 0)
92-
{
93-
return parsedDomainName;
94-
}
95-
int pos = 0;
96-
while(true)
87+
String parsedDomainName;
88+
89+
const uint8_t* pos = buffer + sizeof(DNSHeader);
90+
const uint8_t* end = buffer + packetSize;
91+
92+
// to minimize reallocations due to concats below
93+
// we reserve enough space that a median or average domain
94+
// name size cold be easily contained without a reallocation
95+
// - max size would be 253, in 2013, average is 11 and max was 42
96+
//
97+
parsedDomainName.reserve(32);
98+
99+
uint8_t labelLength = *pos;
100+
101+
while (true)
97102
{
98-
unsigned char labelLength = *(start + pos);
99-
for(int i = 0; i < labelLength; i++)
103+
if (labelLength == 0)
104+
{
105+
// no more labels
106+
downcaseAndRemoveWwwPrefix(parsedDomainName);
107+
return parsedDomainName;
108+
}
109+
110+
// append next label
111+
for (int i = 0; i < labelLength && pos < end; i++)
100112
{
101113
pos++;
102-
parsedDomainName += (char)*(start + pos);
114+
parsedDomainName += static_cast<char>(*pos);
103115
}
104-
pos++;
105-
if (*(start + pos) == 0)
116+
117+
if (pos >= end)
106118
{
107-
downcaseAndRemoveWwwPrefix(parsedDomainName);
108-
return parsedDomainName;
119+
// malformed packet, return an empty domain name
120+
parsedDomainName = "";
121+
return parsedDomainName;
109122
}
110123
else
111124
{
112-
parsedDomainName += ".";
125+
// next label
126+
pos++;
127+
labelLength = *pos;
128+
129+
// if there is another label, add delimiter
130+
if (labelLength != 0)
131+
{
132+
parsedDomainName += ".";
133+
}
113134
}
114135
}
115136
}
116137

117-
void DNSServer::replyWithIP()
138+
void DNSServer::replyWithIP(uint8_t* buffer, size_t packetSize)
118139
{
119-
if (_buffer == NULL) return;
120-
_dnsHeader->QR = DNS_QR_RESPONSE;
121-
_dnsHeader->ANCount = _dnsHeader->QDCount;
122-
_dnsHeader->QDCount = _dnsHeader->QDCount;
123-
//_dnsHeader->RA = 1;
140+
DNSHeader* dnsHeader = reinterpret_cast<DNSHeader*>(buffer);
141+
142+
dnsHeader->QR = DNS_QR_RESPONSE;
143+
dnsHeader->ANCount = dnsHeader->QDCount;
144+
dnsHeader->QDCount = dnsHeader->QDCount;
145+
//dnsHeader->RA = 1;
124146

125147
_udp.beginPacket(_udp.remoteIP(), _udp.remotePort());
126-
_udp.write(_buffer, _currentPacketSize);
148+
_udp.write(buffer, packetSize);
127149

128150
_udp.write((uint8_t)192); // answer name is a pointer
129151
_udp.write((uint8_t)12); // pointer to offset at 0x00c
@@ -142,22 +164,26 @@ void DNSServer::replyWithIP()
142164
_udp.write(_resolvedIP, sizeof(_resolvedIP));
143165
_udp.endPacket();
144166

145-
146-
147167
#ifdef DEBUG_ESP_DNS
148168
DEBUG_ESP_PORT.printf("DNS responds: %s for %s\n",
149-
IPAddress(_resolvedIP).toString().c_str(), getDomainNameWithoutWwwPrefix().c_str() );
169+
IPAddress(_resolvedIP).toString().c_str(), getDomainNameWithoutWwwPrefix(buffer, packetSize).c_str() );
150170
#endif
151171
}
152172

153-
void DNSServer::replyWithCustomCode()
173+
void DNSServer::replyWithCustomCode(uint8_t* buffer, size_t packetSize)
154174
{
155-
if (_buffer == NULL) return;
156-
_dnsHeader->QR = DNS_QR_RESPONSE;
157-
_dnsHeader->RCode = (unsigned char)_errorReplyCode;
158-
_dnsHeader->QDCount = 0;
175+
if (packetSize < sizeof(DNSHeader))
176+
{
177+
return;
178+
}
179+
180+
DNSHeader* dnsHeader = reinterpret_cast<DNSHeader*>(buffer);
181+
182+
dnsHeader->QR = DNS_QR_RESPONSE;
183+
dnsHeader->RCode = (unsigned char)_errorReplyCode;
184+
dnsHeader->QDCount = 0;
159185

160186
_udp.beginPacket(_udp.remoteIP(), _udp.remotePort());
161-
_udp.write(_buffer, sizeof(DNSHeader));
187+
_udp.write(buffer, sizeof(DNSHeader));
162188
_udp.endPacket();
163189
}

libraries/DNSServer/src/DNSServer.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#define DNS_QR_RESPONSE 1
77
#define DNS_OPCODE_QUERY 0
88

9+
#define MAX_DNSNAME_LENGTH 253
10+
911
enum class DNSReplyCode
1012
{
1113
NoError = 0,
@@ -40,6 +42,9 @@ class DNSServer
4042
{
4143
public:
4244
DNSServer();
45+
~DNSServer() {
46+
stop();
47+
};
4348
void processNextRequest();
4449
void setErrorReplyCode(const DNSReplyCode &replyCode);
4550
void setTTL(const uint32_t &ttl);
@@ -56,16 +61,13 @@ class DNSServer
5661
uint16_t _port;
5762
String _domainName;
5863
unsigned char _resolvedIP[4];
59-
int _currentPacketSize;
60-
unsigned char* _buffer;
61-
DNSHeader* _dnsHeader;
6264
uint32_t _ttl;
6365
DNSReplyCode _errorReplyCode;
6466

6567
void downcaseAndRemoveWwwPrefix(String &domainName);
66-
String getDomainNameWithoutWwwPrefix();
67-
bool requestIncludesOnlyOneQuestion();
68-
void replyWithIP();
69-
void replyWithCustomCode();
68+
String getDomainNameWithoutWwwPrefix(const uint8_t* buffer, size_t packetSize);
69+
bool requestIncludesOnlyOneQuestion(const DNSHeader* dnsHeader);
70+
void replyWithIP(uint8_t* buffer, size_t packetSize);
71+
void replyWithCustomCode(uint8_t* buffer, size_t packetSize);
7072
};
7173
#endif

0 commit comments

Comments
 (0)