Commit 777b8e94 authored by Deomid Ryabkov's avatar Deomid Ryabkov

Merge branch 'dev' (Mongoose 6.12)

parents 1f5c3fac 6df64262
......@@ -62,7 +62,7 @@ the functionality:
# Contributions
To submit contributions, sign [Cesanta CLA](https://cesanta.com/cla.html)
and send GitHub pull request. You retain the copyright on your contributions.
and send GitHub pull request.
# Looking for a pre-compiled Mongoose web server Windows or Mac binary?
- [Download pre-compiled Mongoose web server binary.](https://www.cesanta.com/binary.html)
......@@ -6,8 +6,5 @@ signature: |
struct mg_str mg_url_encode(const struct mg_str src);
---
URL-escape the specified string.
All non-printable characters are escaped, plus `._-$,;~()/`.
Input need not be NUL-terminated, but the returned string is.
Returned string is heap-allocated and must be free()'d.
Same as `mg_url_encode_opt(src, "._-$,;~()/", 0)`.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common/cs_dbg.h"
......@@ -19,13 +31,12 @@ enum cs_log_level cs_log_threshold WEAK =
LL_ERROR;
#endif
#if CS_ENABLE_STDIO
static char *s_filter_pattern = NULL;
static size_t s_filter_pattern_len;
void cs_log_set_filter(const char *pattern) WEAK;
#if CS_ENABLE_STDIO
FILE *cs_log_file WEAK = NULL;
#if CS_LOG_ENABLE_TS_DIFF
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_CS_DBG_H_
......@@ -103,11 +115,9 @@ void cs_log_set_file(FILE *file);
* Prints log to the current log file, appends "\n" in the end and flushes the
* stream.
*/
void cs_log_printf(const char *fmt, ...)
#ifdef __GNUC__
__attribute__((format(printf, 1, 2)))
#endif
;
void cs_log_printf(const char *fmt, ...) PRINTF_LIKE(1, 2);
#if CS_ENABLE_STDIO
/*
* Format and print message `x` with the given level `l`. Example:
......@@ -122,6 +132,12 @@ void cs_log_printf(const char *fmt, ...)
if (cs_log_print_prefix(l, __func__, __FILE__)) cs_log_printf x; \
} while (0)
#else
#define LOG(l, x) ((void) l)
#endif
#ifndef CS_NDEBUG
/*
......
/*
* Copyright (c) 2014 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_MD5_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common/cs_time.h"
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_CS_TIME_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_MG_MEM_H_
......
......@@ -92,8 +92,18 @@
/* Common stuff */
#if !defined(PRINTF_LIKE)
#if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__)
#define PRINTF_LIKE(f, a) __attribute__((format(printf, f, a)))
#else
#define PRINTF_LIKE(f, a)
#endif
#endif
#if !defined(WEAK)
#if (defined(__GNUC__) || defined(__TI_COMPILER_VERSION__)) && !defined(_WIN32)
#if (defined(__GNUC__) || defined(__clang__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(_WIN32)
#define WEAK __attribute__((weak))
#else
#define WEAK
......
/*
* Copyright (c) 2014-2017 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
......
/*
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <math.h>
#include "mgos.h"
#include "mgos_system.h"
void (*mgos_nsleep100)(uint32_t n);
uint32_t mgos_nsleep100_loop_count = 0;
/* Provided by arm_nsleep100_{m4,m7}.S for M4 and M7 respectively. */
extern void mgos_nsleep100_impl(uint32_t n);
void mgos_nsleep100_cal(void) {
uint32_t cpu_freq = mgos_get_cpu_freq();
/* # of instruction cycles per 100 ns */
mgos_nsleep100_loop_count =
roundf((100.0f / 1000000000.0f) / (1.0f / cpu_freq));
mgos_nsleep100 = mgos_nsleep100_impl;
}
/*
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.arch armv7e-m
.syntax unified
.thumb
/* These are required to satisfy TI linker. */
.eabi_attribute Tag_ABI_align_needed, 1
.eabi_attribute Tag_ABI_align_preserved, 1
.global mgos_nsleep100_impl
.global mgos_nsleep100_loop_count
.section .iram.mgos_nsleep100_impl
.type mgos_nsleep100_impl, %function
.align 4
mgos_nsleep100_impl:
ldr r3, =mgos_nsleep100_loop_count
ldr r3, [r3]
mul r0, r3
mov r1, #6
udiv r0, r0, r1
cbz r0, xxx
lxx:
subs r0, #1
bne lxx
xxx:
bx lr
.align 4
.size mgos_nsleep100_impl, . - mgos_nsleep100_impl
/*
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.arch armv7e-m
.syntax unified
.thumb
/* These are required to satisfy TI linker. */
.eabi_attribute Tag_ABI_align_needed, 1
.eabi_attribute Tag_ABI_align_preserved, 1
.global mgos_nsleep100_impl
.global mgos_nsleep100_loop_count
.section .iram.mgos_nsleep100_impl
.type mgos_nsleep100_impl, %function
.align 4
mgos_nsleep100_impl:
ldr r3, =mgos_nsleep100_loop_count
ldr r3, [r3]
/* Because of speculative fetch, the core loop only takes 1 cycle. */
muls r0, r3
cbz r0, xxx
lxx:
subs r0, #1
bne lxx
xxx:
bx lr
.align 4
.size mgos_nsleep100_impl, . - mgos_nsleep100_impl
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if CS_PLATFORM == CS_P_CC3200
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Spiffy flasher. Implements strong checksums (MD5) and can use higher
* baud rates. Actual max baud rate will differe from device to device,
* but 921K seems to be common.
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* SLIP protocol is used for communication.
* First packet is a single byte - command number.
* After that, a packet with a variable number of 32-bit (LE) arguments,
* depending on command.
* http://www.apache.org/licenses/LICENSE-2.0
*
* Then command produces variable number of packets of output, but first
* packet of length 1 is the response code: 0 for success, non-zero - error.
*
* See individual command description below.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "stub_flasher.h"
......
/*
* Copyright (c) 2014-2017 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "soc/gpio_reg.h"
......
/*
* Copyright (c) 2014-2017 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
......
/*
* Copyright (c) 2015 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* Stub template.
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <inttypes.h>
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "uart.h"
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_ESP32_STUBS_UART_H_
......
......@@ -25,7 +25,7 @@ $(Q) $(CC_WRAPPER) $(LD) $(LIBDIRS) -T$(LD_SCRIPT) $(LDFLAGS) -o $@ \
endef
define compile_params
$(vecho) "$5 $1 -> $2"
$(vecho) "$5 $1"
$(Q) $(CC_WRAPPER) $3 -MD -MP $(INCDIRS) $4 -c $1 -o $2
endef
......@@ -57,7 +57,8 @@ NO_Os_FLAGS= -fno-expensive-optimizations -fno-thread-jumps \
-fno-tree-pre -fno-tree-vrp
C_CXX_FLAGS = -W -Wall -Werror -Wundef -Wno-comment -Wno-variadic-macros -Wpointer-arith \
-Os $(NO_Os_FLAGS) -g3 \
-Wno-missing-field-initializers \
-pipe -Os $(NO_Os_FLAGS) -g3 \
-Wl,-EL -fno-inline-functions \
-D_XOPEN_SOURCE=500 \
-nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DSTATIC=static \
......@@ -68,7 +69,7 @@ C_CXX_FLAGS = -W -Wall -Werror -Wundef -Wno-comment -Wno-variadic-macros -Wpoin
-DCS_PLATFORM=3 \
-ffunction-sections -fdata-sections
CFLAGS = -std=c99 $(C_CXX_FLAGS)
CFLAGS = -std=gnu99 $(C_CXX_FLAGS)
CXXFLAGS = -std=gnu++11 -fno-exceptions $(C_CXX_FLAGS)
# linker flags used to generate the main object file
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "mongoose/mongoose.h"
#include "mongoose.h"
#ifdef RTOS_SDK
#include "esp_libc.h"
......
/*
* Copyright (c) 2014-2017 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_ESP8266_ESP_HW_WDT_REGISTER_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_ESP8266_ESP_MISSING_INCLUDES_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_ESP8266_ESP_SSL_KRYPTON_H_
......
/*
* Copyright (c) 2014 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
......
/*
* Copyright (c) 2014 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if ESP_UMM_ENABLE
......
......@@ -160,7 +160,8 @@ static uint8 calc_chksum(uint8 *start, uint8 *end) {
}
#endif
#define UART_CLKDIV_26MHZ(B) (52000000 + B / 2) / B
#define UART_CLKDIV_80MHZ(B) (80000000 + B / 2) / B
#define UART_CLKDIV_52MHZ(B) (52000000 + B / 2) / B
// prevent this function being placed inline with main
// to keep main's stack size as small as possible
......@@ -182,10 +183,23 @@ uint32 NOINLINE find_image(void) {
// delay to slow boot (help see messages when debugging)
//ets_delay_us(2000000);
uart_div_modify(0, UART_CLKDIV_26MHZ(115200));
/*
* UART divider depends on the APB frequency. Cold boot starts with 52MHz APB,
* SDK configures PLL, sets it to 80 and it persists across soft reset
* so on soft reset a different divider should be used. What we really want to
* know is if the PLL is running but since that is completely undocumented
* we use CPU frequency bit as a workaround: mos sets CPU to 160 MHz on startup
* so we assume that if frequency is preserved, then it's soft reset, PLL is
* running and APB is at 80 MHz.
*/
if (READ_PERI_REG(0x3ff00014) & 1) {
uart_div_modify(0, UART_CLKDIV_80MHZ(115200));
} else {
uart_div_modify(0, UART_CLKDIV_52MHZ(115200));
}
ets_delay_us(1000);
ets_printf("\r\nrBoot v1.2.1 - richardaburton@gmail.com\r\n");
ets_printf("\r\nrBoot v1.2.1-cesanta1 - richardaburton@gmail.com\r\n");
// read rom header
SPIRead(0, header, sizeof(rom_header));
......
......@@ -23,7 +23,7 @@ LD := $(addprefix $(XTENSA_BINDIR)/,xtensa-lx106-elf-gcc)
endif
CC_WRAPPER ?=
CFLAGS = -Os -O3 -Wpointer-arith -Wundef -Werror -Wl,-EL \
CFLAGS = -Os -Wpointer-arith -Wundef -Werror -Wl,-EL \
-fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals \
-D__ets__ -DIRAM='__attribute__((section(".fast.text")))' \
-DNOINSTR='__attribute__((no_instrument_function))' \
......
/*
* Copyright (c) 2015 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* Stub template.
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <inttypes.h>
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "uart.h"
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_ESP8266_STUBS_UART_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
......@@ -41,24 +53,17 @@ void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) {
(struct mg_ev_mgr_lwip_data *) mgr->ifaces[MG_MAIN_IFACE]->data;
while (md->sig_queue_len > 0) {
mgos_lock();
int sig = md->sig_queue[md->start_index].sig;
struct mg_connection *nc = md->sig_queue[md->start_index].nc;
int i = md->start_index;
int sig = md->sig_queue[i].sig;
struct mg_connection *nc = md->sig_queue[i].nc;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
md->start_index = (md->start_index + 1) % MG_SIG_QUEUE_LEN;
md->start_index = (i + 1) % MG_SIG_QUEUE_LEN;
md->sig_queue_len--;
mgos_unlock();
if (nc->iface == NULL || nc->mgr == NULL) continue;
switch (sig) {
case MG_SIG_CONNECT_RESULT: {
#if MG_ENABLE_SSL
if (cs->err == 0 && (nc->flags & MG_F_SSL) &&
!(nc->flags & MG_F_SSL_HANDSHAKE_DONE)) {
mg_lwip_ssl_do_hs(nc);
} else
#endif
{
mg_if_connect_cb(nc, cs->err);
}
break;
}
case MG_SIG_CLOSE_CONN: {
......@@ -68,11 +73,8 @@ void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) {
}
case MG_SIG_RECV: {
cs->recv_pending = 0;
if (nc->flags & MG_F_UDP) {
mg_lwip_handle_recv_udp(nc);
} else {
mg_lwip_handle_recv_tcp(nc);
}
mg_if_can_recv_cb(nc);
mbuf_trim(&nc->recv_mbuf);
break;
}
case MG_SIG_TOMBSTONE: {
......@@ -87,7 +89,8 @@ void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) {
}
void mg_lwip_if_init(struct mg_iface *iface) {
LOG(LL_INFO, ("%p Mongoose init", iface));
LOG(LL_INFO, ("Mongoose %s, LwIP %u.%u.%u", MG_VERSION, LWIP_VERSION_MAJOR,
LWIP_VERSION_MINOR, LWIP_VERSION_REVISION));
iface->data = MG_CALLOC(1, sizeof(struct mg_ev_mgr_lwip_data));
}
......@@ -126,42 +129,7 @@ time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
tmp = nc->next;
n++;
if ((nc->flags & MG_F_CLOSE_IMMEDIATELY) ||
((nc->flags & MG_F_SEND_AND_CLOSE) && (nc->flags & MG_F_UDP) &&
(nc->send_mbuf.len == 0))) {
mg_close_conn(nc);
continue;
}
mg_if_poll(nc, now);
mg_if_timer(nc, now);
#if MG_ENABLE_SSL
if ((nc->flags & MG_F_SSL) && cs != NULL && cs->pcb.tcp != NULL &&
cs->pcb.tcp->state == ESTABLISHED) {
if (((nc->flags & MG_F_WANT_WRITE) ||
((nc->send_mbuf.len > 0) &&
(nc->flags & MG_F_SSL_HANDSHAKE_DONE))) &&
cs->pcb.tcp->snd_buf > 0) {
/* Can write more. */
if (nc->flags & MG_F_SSL_HANDSHAKE_DONE) {
if (!(nc->flags & MG_F_CONNECTING)) mg_lwip_ssl_send(nc);
} else {
mg_lwip_ssl_do_hs(nc);
}
}
if (cs->rx_chain != NULL || (nc->flags & MG_F_WANT_READ)) {
if (nc->flags & MG_F_SSL_HANDSHAKE_DONE) {
if (!(nc->flags & MG_F_CONNECTING)) mg_lwip_ssl_recv(nc);
} else {
mg_lwip_ssl_do_hs(nc);
}
}
} else
#endif /* MG_ENABLE_SSL */
{
if (nc->send_mbuf.len > 0 && !(nc->flags & MG_F_CONNECTING)) {
mg_lwip_send_more(nc);
}
}
if (!mg_if_poll(nc, now)) continue;
if (nc->sock != INVALID_SOCKET &&
!(nc->flags & (MG_F_UDP | MG_F_LISTENING)) && cs->pcb.tcp != NULL &&
cs->pcb.tcp->unsent != NULL) {
......@@ -175,14 +143,17 @@ time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) {
}
if (nc->sock != INVALID_SOCKET) {
/* Try to consume data from cs->rx_chain */
mg_lwip_consume_rx_chain_tcp(nc);
if (mg_lwip_if_can_send(nc, cs)) {
mg_if_can_send_cb(nc);
mbuf_trim(&nc->send_mbuf);
}
if (cs->rx_chain != NULL) {
mg_if_can_recv_cb(nc);
} else if (cs->draining_rx_chain) {
/*
* If the connection is about to close, and rx_chain is finally empty,
* send the MG_SIG_CLOSE_CONN signal
*/
if (cs->draining_rx_chain && cs->rx_chain == NULL) {
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
}
}
......@@ -210,21 +181,9 @@ uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr) {
}
num_timers++;
}
if (nc->send_mbuf.len > 0
#if MG_ENABLE_SSL
|| (nc->flags & MG_F_WANT_WRITE)
#endif
) {
int can_send = 0;
/* We have stuff to send, but can we? */
if (nc->flags & MG_F_UDP) {
/* UDP is always ready for sending. */
can_send = (cs->pcb.udp != NULL);
} else {
can_send = (cs->pcb.tcp != NULL && cs->pcb.tcp->snd_buf > 0);
}
/* We want and can send, request a poll immediately. */
if (can_send) return 0;
/* We want and can send data, request a poll immediately. */
if (nc->sock != INVALID_SOCKET && mg_lwip_if_can_send(nc, cs)) {
return 0;
}
}
uint32_t timeout_ms = ~0;
......
This diff is collapsed.
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_LWIP_MG_NET_IF_LWIP_H_
......@@ -30,9 +42,9 @@ struct mg_lwip_conn_state {
/* Last SSL write size, for retries. */
int last_ssl_write_size;
/* Whether MG_SIG_RECV is already pending for this connection */
int recv_pending : 1;
int recv_pending;
/* Whether the connection is about to close, just `rx_chain` needs to drain */
int draining_rx_chain : 1;
int draining_rx_chain;
};
enum mg_sig_type {
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* All rights reserved
*/
#if MG_ENABLE_SSL && MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
#include "common/mg_mem.h"
#include "common/cs_dbg.h"
#include <lwip/pbuf.h>
#include <lwip/tcp.h>
#ifndef MG_LWIP_SSL_IO_SIZE
#define MG_LWIP_SSL_IO_SIZE 1024
#endif
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
void mg_lwip_ssl_do_hs(struct mg_connection *nc) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
int server_side = (nc->listener != NULL);
enum mg_ssl_if_result res;
if (nc->flags & MG_F_CLOSE_IMMEDIATELY) return;
res = mg_ssl_if_handshake(nc);
DBG(("%p %lu %d %d", nc, nc->flags, server_side, res));
if (res != MG_SSL_OK) {
if (res == MG_SSL_WANT_WRITE) {
nc->flags |= MG_F_WANT_WRITE;
cs->err = 0;
} else if (res == MG_SSL_WANT_READ) {
/*
* Nothing to do in particular, we are callback-driven.
* What we definitely do not need anymore is SSL reading (nothing left).
*/
nc->flags &= ~MG_F_WANT_READ;
cs->err = 0;
} else {
cs->err = res;
if (server_side) {
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
} else {
mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);
}
}
} else {
cs->err = 0;
nc->flags &= ~MG_F_WANT_WRITE;
/*
* Handshake is done. Schedule a read immediately to consume app data
* which may already be waiting.
*/
nc->flags |= (MG_F_SSL_HANDSHAKE_DONE | MG_F_WANT_READ);
if (server_side) {
mg_lwip_accept_conn(nc, cs->pcb.tcp);
} else {
mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);
}
}
}
void mg_lwip_ssl_send(struct mg_connection *nc) {
if (nc->sock == INVALID_SOCKET) {
DBG(("%p invalid socket", nc));
return;
}
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
/* It's ok if the buffer is empty. Return value of 0 may also be valid. */
int len = cs->last_ssl_write_size;
if (len == 0) {
len = MIN(MG_LWIP_SSL_IO_SIZE, nc->send_mbuf.len);
}
int ret = mg_ssl_if_write(nc, nc->send_mbuf.buf, len);
DBG(("%p SSL_write %u = %d", nc, len, ret));
if (ret > 0) {
mg_if_sent_cb(nc, ret);
cs->last_ssl_write_size = 0;
} else if (ret < 0) {
/* This is tricky. We must remember the exact data we were sending to retry
* exactly the same send next time. */
cs->last_ssl_write_size = len;
}
if (ret == len) {
nc->flags &= ~MG_F_WANT_WRITE;
} else if (ret == MG_SSL_WANT_WRITE) {
nc->flags |= MG_F_WANT_WRITE;
} else {
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
}
}
void mg_lwip_ssl_recv(struct mg_connection *nc) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
/* Don't deliver data before connect callback */
if (nc->flags & MG_F_CONNECTING) return;
while (nc->recv_mbuf.len < nc->recv_mbuf_limit) {
char *buf = (char *) MG_MALLOC(MG_LWIP_SSL_IO_SIZE);
if (buf == NULL) return;
int ret = mg_ssl_if_read(nc, buf, MG_LWIP_SSL_IO_SIZE);
DBG(("%p %p SSL_read %u = %d", nc, cs->rx_chain, MG_LWIP_SSL_IO_SIZE, ret));
if (ret <= 0) {
MG_FREE(buf);
if (ret == MG_SSL_WANT_WRITE) {
nc->flags |= MG_F_WANT_WRITE;
return;
} else if (ret == MG_SSL_WANT_READ) {
/*
* Nothing to do in particular, we are callback-driven.
* What we definitely do not need anymore is SSL reading (nothing left).
*/
nc->flags &= ~MG_F_WANT_READ;
cs->err = 0;
return;
} else {
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
return;
}
} else {
mg_if_recv_tcp_cb(nc, buf, ret, 1 /* own */);
}
}
}
#ifdef KR_VERSION
ssize_t kr_send(int fd, const void *buf, size_t len) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) fd;
int ret = mg_lwip_tcp_write(cs->nc, buf, len);
DBG(("%p mg_lwip_tcp_write %u = %d", cs->nc, len, ret));
if (ret == 0) ret = KR_IO_WOULDBLOCK;
return ret;
}
ssize_t kr_recv(int fd, void *buf, size_t len) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) fd;
struct pbuf *seg = cs->rx_chain;
if (seg == NULL) {
DBG(("%u - nothing to read", len));
return KR_IO_WOULDBLOCK;
}
size_t seg_len = (seg->len - cs->rx_offset);
DBG(("%u %u %u %u", len, cs->rx_chain->len, seg_len, cs->rx_chain->tot_len));
len = MIN(len, seg_len);
pbuf_copy_partial(seg, buf, len, cs->rx_offset);
cs->rx_offset += len;
tcp_recved(cs->pcb.tcp, len);
if (cs->rx_offset == cs->rx_chain->len) {
cs->rx_chain = pbuf_dechain(cs->rx_chain);
pbuf_free(seg);
cs->rx_offset = 0;
}
return len;
}
#elif MG_SSL_IF == MG_SSL_IF_MBEDTLS
int ssl_socket_send(void *ctx, const unsigned char *buf, size_t len) {
struct mg_connection *nc = (struct mg_connection *) ctx;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
int ret = mg_lwip_tcp_write(cs->nc, buf, len);
if (ret == 0) ret = MBEDTLS_ERR_SSL_WANT_WRITE;
LOG(LL_DEBUG, ("%p %d -> %d", nc, len, ret));
return ret;
}
int ssl_socket_recv(void *ctx, unsigned char *buf, size_t len) {
struct mg_connection *nc = (struct mg_connection *) ctx;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
struct pbuf *seg = cs->rx_chain;
if (seg == NULL) {
DBG(("%u - nothing to read", len));
return MBEDTLS_ERR_SSL_WANT_READ;
}
size_t seg_len = (seg->len - cs->rx_offset);
DBG(("%u %u %u %u", len, cs->rx_chain->len, seg_len, cs->rx_chain->tot_len));
mgos_lock();
len = MIN(len, seg_len);
pbuf_copy_partial(seg, buf, len, cs->rx_offset);
cs->rx_offset += len;
/* TCP PCB may be NULL if connection has already been closed
* but we still have data to deliver to SSL. */
if (cs->pcb.tcp != NULL) tcp_recved(cs->pcb.tcp, len);
if (cs->rx_offset == cs->rx_chain->len) {
cs->rx_chain = pbuf_dechain(cs->rx_chain);
pbuf_free(seg);
cs->rx_offset = 0;
}
mgos_unlock();
LOG(LL_DEBUG, ("%p <- %d", nc, (int) len));
return len;
}
#endif
#endif /* MG_ENABLE_SSL && MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL */
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common/platform.h"
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if CS_PLATFORM == CS_P_MSP432
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if (CS_PLATFORM == CS_P_NRF51 || CS_PLATFORM == CS_P_NRF52) && \
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if MG_ENABLE_NET_IF_PIC32
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PIC32_NET_IF_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3220_H_
......@@ -22,7 +34,9 @@
#endif
#define MG_NET_IF MG_NET_IF_SIMPLELINK
#ifndef MG_SSL_IF
#define MG_SSL_IF MG_SSL_IF_SIMPLELINK
#endif
/* Only SPIFFS supports directories, SLFS does not. */
#if defined(CC3220_FS_SPIFFS) && !defined(MG_ENABLE_DIRECTORY_LISTING)
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP32_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_
......@@ -30,10 +42,6 @@ typedef struct stat cs_stat_t;
#define __cdecl
#define _FILE_OFFSET_BITS 32
#if !defined(RTOS_SDK) && !defined(__cplusplus)
#define fileno(x) -1
#endif
#define MG_LWIP 1
/* struct timeval is defined in sys/time.h. */
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_MBED_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_
#define CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_
#define CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_PIC32_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_STM32_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if MG_NET_IF == MG_NET_IF_SIMPLELINK && \
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Standard libc interface to TI SimpleLink FS. */
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_SL_FS_SLFS_H_
......
This diff is collapsed.
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_SL_NET_IF_H_
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if MG_NET_IF == MG_NET_IF_SIMPLELINK
......
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_SIMPLELINK
......@@ -54,6 +66,31 @@ enum mg_ssl_if_result mg_ssl_if_conn_init(
return MG_SSL_OK;
}
enum mg_ssl_if_result mg_ssl_if_conn_accept(struct mg_connection *nc,
struct mg_connection *lc) {
/* SimpleLink does everything for us, nothing for us to do. */
(void) nc;
(void) lc;
return MG_SSL_OK;
}
enum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc) {
/* SimpleLink has already performed the handshake, nothing to do. */
return MG_SSL_OK;
}
int mg_ssl_if_read(struct mg_connection *nc, void *buf, size_t len) {
/* SimpelLink handles TLS, so this is just a pass-through. */
int n = nc->iface->vtable->tcp_recv(nc, buf, len);
if (n == 0) nc->flags |= MG_F_WANT_READ;
return n;
}
int mg_ssl_if_write(struct mg_connection *nc, const void *buf, size_t len) {
/* SimpelLink handles TLS, so this is just a pass-through. */
return nc->iface->vtable->tcp_send(nc, buf, len);
}
void mg_ssl_if_conn_close_notify(struct mg_connection *nc) {
/* Nothing to do */
(void) nc;
......@@ -154,38 +191,42 @@ int sl_set_ssl_opts(int sock, struct mg_connection *nc) {
const struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *) nc->ssl_if_data;
DBG(("%p ssl ctx: %p", nc, ctx));
if (ctx != NULL) {
if (ctx == NULL) return 0;
DBG(("%p %s,%s,%s,%s", nc, (ctx->ssl_cert ? ctx->ssl_cert : "-"),
(ctx->ssl_key ? ctx->ssl_cert : "-"),
(ctx->ssl_ca_cert ? ctx->ssl_ca_cert : "-"),
(ctx->ssl_server_name ? ctx->ssl_server_name : "-")));
if (ctx->ssl_cert != NULL && ctx->ssl_key != NULL) {
char *ssl_cert = sl_pem2der(ctx->ssl_cert);
char *ssl_key = sl_pem2der(ctx->ssl_key);
if (ssl_cert != NULL && ssl_key != NULL) {
char *ssl_cert = sl_pem2der(ctx->ssl_cert), *ssl_key = NULL;
if (ssl_cert != NULL) {
err = sl_SetSockOpt(sock, SL_SOL_SOCKET,
SL_SO_SECURE_FILES_CERTIFICATE_FILE_NAME, ssl_cert,
strlen(ssl_cert));
LOG(LL_INFO, ("CERTIFICATE_FILE_NAME %s -> %d", ssl_cert, err));
MG_FREE(ssl_cert);
LOG(LL_DEBUG, ("CERTIFICATE_FILE_NAME %s -> %d", ssl_cert, err));
ssl_key = sl_pem2der(ctx->ssl_key);
if (ssl_key != NULL) {
err = sl_SetSockOpt(sock, SL_SOL_SOCKET,
SL_SO_SECURE_FILES_PRIVATE_KEY_FILE_NAME, ssl_key,
strlen(ssl_key));
LOG(LL_INFO, ("PRIVATE_KEY_FILE_NAME %s -> %d", ssl_key, err));
MG_FREE(ssl_key);
LOG(LL_DEBUG, ("PRIVATE_KEY_FILE_NAME %s -> %d", ssl_key, err));
} else {
err = -1;
}
} else {
err = -1;
}
MG_FREE(ssl_cert);
MG_FREE(ssl_key);
if (err != 0) return err;
}
if (ctx->ssl_ca_cert != NULL) {
if (ctx->ssl_ca_cert[0] != '\0') {
char *ssl_ca_cert = sl_pem2der(ctx->ssl_ca_cert);
if (ssl_ca_cert != NULL) {
err = sl_SetSockOpt(sock, SL_SOL_SOCKET,
SL_SO_SECURE_FILES_CA_FILE_NAME, ssl_ca_cert,
strlen(ssl_ca_cert));
LOG(LL_INFO, ("CA_FILE_NAME %s -> %d", ssl_ca_cert, err));
err =
sl_SetSockOpt(sock, SL_SOL_SOCKET, SL_SO_SECURE_FILES_CA_FILE_NAME,
ssl_ca_cert, strlen(ssl_ca_cert));
LOG(LL_DEBUG, ("CA_FILE_NAME %s -> %d", ssl_ca_cert, err));
} else {
err = -1;
}
......@@ -204,7 +245,6 @@ int sl_set_ssl_opts(int sock, struct mg_connection *nc) {
* so we ignore the error. */
if (err != 0 && err != SL_ERROR_BSD_ENOPROTOOPT) return err;
}
}
return 0;
}
......
/*
* Copyright (c) 2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef WINCE
......
/*
* Copyright (c) 2017 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef _WIN32
......
/*
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common/cs_dbg.h"
#include "common/test_main.h"
#include "common/test_util.h"
#if defined(_MSC_VER) && _MSC_VER >= 1900
#include <crtdbg.h>
int __cdecl CrtDbgHook(int nReportType, char *szMsg, int *pnRet) {
(void) nReportType;
(void) szMsg;
(void) pnRet;
fprintf(stderr, "CRT debug hook: type: %d, msg: %s\n", nReportType, szMsg);
/* Return true - Abort,Retry,Ignore dialog will *not* be displayed */
return 1;
}
#endif
#ifndef __cdecl
#define __cdecl
#endif
int g_num_tests = 0;
int g_num_checks = 0;
const char *g_argv_0 = NULL;
int __cdecl main(int argc, char *argv[]) {
const char *fail_msg;
const char *filter = argc > 1 ? argv[1] : "";
char *seed_str = getenv("TEST_SEED");
double started;
int seed = 0;
if (seed_str != NULL) {
seed = atoi(seed_str);
} else {
seed = (int) time(NULL);
}
printf("seed: %d\n", seed);
srand(seed);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
#if defined(_MSC_VER) && _MSC_VER >= 1900
/* NOTE: not available on wine/vc6 */
_CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, CrtDbgHook);
#endif
g_argv_0 = argv[0];
tests_setup();
started = cs_time();
fail_msg = tests_run(filter);
printf("%s, ran %d tests (%d checks) in %.3lfs\n", fail_msg ? "FAIL" : "PASS",
g_num_tests, g_num_checks, cs_time() - started);
tests_teardown();
if (fail_msg != NULL) {
/* Prevent leak analyzer from running: there will be "leaks" because of
* premature return from the test, and in this case we don't care. */
_exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
/*
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CS_COMMON_TEST_MAIN_H_
#define CS_COMMON_TEST_MAIN_H_
#ifdef __cplusplus
extern "C" {
#endif
void tests_setup(void);
const char *tests_run(const char *filter);
void tests_teardown(void);
extern const char *g_argv_0;
#ifdef __cplusplus
}
#endif
#endif /* CS_COMMON_TEST_MAIN_H_ */
/*
* Copyright (c) 2014-2016 Cesanta Software Limited
* Copyright (c) 2014-2018 Cesanta Software Limited
* All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the ""License"");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an ""AS IS"" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common/test_util.h"
......
This diff is collapsed.
......@@ -20,7 +20,7 @@
#ifndef CS_MONGOOSE_SRC_COMMON_H_
#define CS_MONGOOSE_SRC_COMMON_H_
#define MG_VERSION "6.11"
#define MG_VERSION "6.12"
/* Local tweaks, applied before any of Mongoose's own headers. */
#ifdef MG_LOCALS
......
......@@ -127,7 +127,6 @@ enum mg_http_multipart_stream_state {
MPS_BEGIN,
MPS_WAITING_FOR_BOUNDARY,
MPS_WAITING_FOR_CHUNK,
MPS_GOT_CHUNK,
MPS_GOT_BOUNDARY,
MPS_FINALIZE,
MPS_FINISHED
......@@ -139,7 +138,6 @@ struct mg_http_multipart_stream {
const char *var_name;
const char *file_name;
void *user_data;
int prev_io_len;
enum mg_http_multipart_stream_state state;
int processing_part;
};
......@@ -787,6 +785,7 @@ void mg_http_handler(struct mg_connection *nc, int ev,
}
#endif /* MG_ENABLE_HTTP_STREAMING_MULTIPART */
again:
req_len = mg_parse_http(io->buf, io->len, hm, is_req);
if (req_len > 0 &&
......@@ -880,7 +879,10 @@ void mg_http_handler(struct mg_connection *nc, int ev,
/* Whole HTTP message is fully buffered, call event handler */
mg_http_call_endpoint_handler(nc, trigger_ev, hm);
mbuf_remove(io, hm->message.len);
pd->rcvd = 0;
pd->rcvd -= hm->message.len;
if (io->len > 0) {
goto again;
}
}
}
}
......@@ -971,19 +973,6 @@ static void mg_http_multipart_call_handler(struct mg_connection *c, int ev,
pd->mp_stream.user_data = mp.user_data;
}
static int mg_http_multipart_got_chunk(struct mg_connection *c) {
struct mg_http_proto_data *pd = mg_http_get_proto_data(c);
struct mbuf *io = &c->recv_mbuf;
mg_http_multipart_call_handler(c, MG_EV_HTTP_PART_DATA, io->buf,
pd->mp_stream.prev_io_len);
mbuf_remove(io, pd->mp_stream.prev_io_len);
pd->mp_stream.prev_io_len = 0;
pd->mp_stream.state = MPS_WAITING_FOR_CHUNK;
return 0;
}
static int mg_http_multipart_finalize(struct mg_connection *c) {
struct mg_http_proto_data *pd = mg_http_get_proto_data(c);
......@@ -1118,19 +1107,18 @@ static int mg_http_multipart_continue_wait_for_chunk(struct mg_connection *c) {
}
boundary = c_strnstr(io->buf, pd->mp_stream.boundary, io->len);
if (boundary == NULL && pd->mp_stream.prev_io_len == 0) {
pd->mp_stream.prev_io_len = io->len;
if (boundary == NULL) {
int data_size = (io->len - (pd->mp_stream.boundary_len + 6));
if (data_size > 0) {
mg_http_multipart_call_handler(c, MG_EV_HTTP_PART_DATA, io->buf,
data_size);
mbuf_remove(io, data_size);
}
return 0;
} else if (boundary == NULL &&
(int) io->len >
pd->mp_stream.prev_io_len + pd->mp_stream.boundary_len + 4) {
pd->mp_stream.state = MPS_GOT_CHUNK;
return 1;
} else if (boundary != NULL) {
int data_size = (boundary - io->buf - 4);
mg_http_multipart_call_handler(c, MG_EV_HTTP_PART_DATA, io->buf, data_size);
mbuf_remove(io, (boundary - io->buf));
pd->mp_stream.prev_io_len = 0;
pd->mp_stream.state = MPS_WAITING_FOR_BOUNDARY;
return 1;
} else {
......@@ -1164,12 +1152,6 @@ static void mg_http_multipart_continue(struct mg_connection *c) {
}
break;
}
case MPS_GOT_CHUNK: {
if (mg_http_multipart_got_chunk(c) == 0) {
return;
}
break;
}
case MPS_FINALIZE: {
if (mg_http_multipart_finalize(c) == 0) {
return;
......@@ -1177,7 +1159,6 @@ static void mg_http_multipart_continue(struct mg_connection *c) {
break;
}
case MPS_FINISHED: {
mbuf_remove(&c->recv_mbuf, c->recv_mbuf.len);
return;
}
}
......@@ -1329,8 +1310,11 @@ const char *mg_status_message(int status_code) {
void mg_send_response_line_s(struct mg_connection *nc, int status_code,
const struct mg_str extra_headers) {
mg_printf(nc, "HTTP/1.1 %d %s\r\nServer: %s\r\n", status_code,
mg_status_message(status_code), mg_version_header);
mg_printf(nc, "HTTP/1.1 %d %s\r\n", status_code,
mg_status_message(status_code));
#ifndef MG_HIDE_SERVER_INFO
mg_printf(nc, "Server: %s\r\n", mg_version_header);
#endif
if (extra_headers.len > 0) {
mg_printf(nc, "%.*s\r\n", (int) extra_headers.len, extra_headers.p);
}
......@@ -1662,7 +1646,7 @@ void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...) {
static void mg_http_parse_header_internal(struct mg_str *hdr,
const char *var_name,
struct altbuf *ab) {
int ch = ' ', ch1 = ',', n = strlen(var_name);
int ch = ' ', ch1 = ',', ch2 = ';', n = strlen(var_name);
const char *p, *end = hdr ? hdr->p + hdr->len : NULL, *s = NULL;
/* Find where variable starts */
......@@ -1675,10 +1659,10 @@ static void mg_http_parse_header_internal(struct mg_str *hdr,
if (s != NULL && &s[n + 1] < end) {
s += n + 1;
if (*s == '"' || *s == '\'') {
ch = ch1 = *s++;
ch = ch1 = ch2 = *s++;
}
p = s;
while (p < end && p[0] != ch && p[0] != ch1) {
while (p < end && p[0] != ch && p[0] != ch1 && p[0] != ch2) {
if (ch != ' ' && p[0] == '\\' && p[1] == ch) p++;
altbuf_append(ab, *p++);
}
......@@ -2042,7 +2026,7 @@ static void mg_scan_directory(struct mg_connection *nc, const char *dir,
const struct mg_serve_http_opts *opts,
void (*func)(struct mg_connection *, const char *,
cs_stat_t *)) {
char path[MG_MAX_PATH];
char path[MG_MAX_PATH + 1];
cs_stat_t st;
struct dirent *dp;
DIR *dirp;
......@@ -2728,8 +2712,7 @@ void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
case MG_EV_HTTP_PART_BEGIN: {
struct mg_http_multipart_part *mp =
(struct mg_http_multipart_part *) ev_data;
struct file_upload_state *fus =
(struct file_upload_state *) MG_CALLOC(1, sizeof(*fus));
struct file_upload_state *fus;
struct mg_str lfn = local_name_fn(nc, mg_mk_str(mp->file_name));
mp->user_data = NULL;
if (lfn.p == NULL || lfn.len == 0) {
......@@ -2743,6 +2726,11 @@ void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
nc->flags |= MG_F_SEND_AND_CLOSE;
return;
}
fus = (struct file_upload_state *) MG_CALLOC(1, sizeof(*fus));
if (fus == NULL) {
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
return;
}
fus->lfn = (char *) MG_MALLOC(lfn.len + 1);
memcpy(fus->lfn, lfn.p, lfn.len);
fus->lfn[lfn.len] = '\0';
......@@ -2814,12 +2802,6 @@ void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
if (mp->status >= 0 && fus->fp != NULL) {
LOG(LL_DEBUG, ("%p Uploaded %s (%s), %d bytes", nc, mp->file_name,
fus->lfn, (int) fus->num_recd));
mg_printf(nc,
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Connection: close\r\n\r\n"
"Ok, %s - %d bytes.\r\n",
mp->file_name, (int) fus->num_recd);
} else {
LOG(LL_ERROR, ("Failed to store %s (%s)", mp->file_name, fus->lfn));
/*
......@@ -2831,6 +2813,15 @@ void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
MG_FREE(fus->lfn);
MG_FREE(fus);
mp->user_data = NULL;
/* Don't close the connection yet, there may be more files to come. */
break;
}
case MG_EV_HTTP_MULTIPART_REQUEST_END: {
mg_printf(nc,
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Connection: close\r\n\r\n"
"Ok.\r\n");
nc->flags |= MG_F_SEND_AND_CLOSE;
break;
}
......
......@@ -478,7 +478,6 @@ MG_INTERNAL void mg_handle_cgi(struct mg_connection *nc, const char *prog,
if (mg_start_process(opts->cgi_interpreter, prog, blk.buf, blk.vars, dir,
fds[1]) != 0) {
size_t n = nc->recv_mbuf.len - (hm->message.len - hm->body.len);
struct mg_connection *cgi_nc =
mg_add_sock(nc->mgr, fds[0], mg_cgi_ev_handler MG_UD_ARG(nc));
struct mg_http_proto_data *cgi_pd = mg_http_get_proto_data(nc);
......@@ -488,8 +487,8 @@ MG_INTERNAL void mg_handle_cgi(struct mg_connection *nc, const char *prog,
#endif
nc->flags |= MG_F_HTTP_CGI_PARSE_HEADERS;
/* Push POST data to the CGI */
if (n > 0 && n < nc->recv_mbuf.len) {
mg_send(cgi_pd->cgi.cgi_nc, hm->body.p, n);
if (hm->body.len > 0) {
mg_send(cgi_pd->cgi.cgi_nc, hm->body.p, hm->body.len);
}
mbuf_remove(&nc->recv_mbuf, nc->recv_mbuf.len);
} else {
......
......@@ -64,9 +64,9 @@ int mg_http_parse_header2(struct mg_str *hdr, const char *var_name, char **buf,
int mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf,
size_t buf_size)
#ifdef __GNUC__
__attribute__((deprecated));
__attribute__((deprecated))
#endif
;
;
/*
* Gets and parses the Authorization: Basic header
......
......@@ -8,6 +8,7 @@ HEADERS = mg_common.h \
$(COMMON)/platforms/platform_esp8266.h \
$(COMMON)/platforms/platform_cc3100.h \
$(COMMON)/platforms/platform_cc3200.h \
$(COMMON)/platforms/platform_cc3220.h \
$(COMMON)/platforms/platform_msp432.h \
$(COMMON)/platforms/platform_tm4c129.h \
$(COMMON)/platforms/platform_mbed.h \
......@@ -96,7 +97,6 @@ SOURCES = $(COMMON)/mg_mem.h \
$(COMMON)/platforms/lwip/mg_lwip_net_if.h \
$(COMMON)/platforms/lwip/mg_lwip_net_if.c \
$(COMMON)/platforms/lwip/mg_lwip_ev_mgr.c \
$(COMMON)/platforms/lwip/mg_lwip_ssl_if.c \
$(COMMON)/platforms/wince/wince_libc.c \
$(COMMON)/platforms/pic32/pic32_net_if.h \
$(COMMON)/platforms/pic32/pic32_net_if.c \
......
......@@ -228,18 +228,13 @@ void mg_set_protocol_mqtt(struct mg_connection *nc) {
nc->proto_data_destructor = mg_mqtt_proto_data_destructor;
}
static void mg_mqtt_prepend_header(struct mg_connection *nc, uint8_t cmd,
static void mg_send_mqtt_header(struct mg_connection *nc, uint8_t cmd,
uint8_t flags, size_t len) {
struct mg_mqtt_proto_data *pd = (struct mg_mqtt_proto_data *) nc->proto_data;
size_t off = nc->send_mbuf.len - len;
uint8_t header = cmd << 4 | (uint8_t) flags;
uint8_t buf[1 + sizeof(size_t)];
uint8_t *vlen = &buf[1];
assert(nc->send_mbuf.len >= len);
buf[0] = header;
buf[0] = (cmd << 4) | flags;
/* mqtt variable length encoding */
do {
......@@ -249,7 +244,7 @@ static void mg_mqtt_prepend_header(struct mg_connection *nc, uint8_t cmd,
vlen++;
} while (len > 0);
mbuf_insert(&nc->send_mbuf, off, buf, vlen - buf);
mg_send(nc, buf, vlen - buf);
pd->last_control_time = mg_time();
}
......@@ -260,11 +255,16 @@ void mg_send_mqtt_handshake(struct mg_connection *nc, const char *client_id) {
void mg_send_mqtt_handshake_opt(struct mg_connection *nc, const char *client_id,
struct mg_send_mqtt_handshake_opts opts) {
uint16_t hlen, nlen, rem_len = 0;
struct mg_mqtt_proto_data *pd = (struct mg_mqtt_proto_data *) nc->proto_data;
uint16_t id_len = 0, wt_len = 0, wm_len = 0, user_len = 0, pw_len = 0;
uint16_t netbytes;
size_t total_len;
mg_send(nc, "\00\04MQTT\04", 7);
rem_len += 7;
if (client_id != NULL) {
id_len = strlen(client_id);
}
total_len = 7 + 1 + 2 + 2 + id_len;
if (opts.user_name != NULL) {
opts.flags |= MG_MQTT_HAS_USER_NAME;
......@@ -273,56 +273,58 @@ void mg_send_mqtt_handshake_opt(struct mg_connection *nc, const char *client_id,
opts.flags |= MG_MQTT_HAS_PASSWORD;
}
if (opts.will_topic != NULL && opts.will_message != NULL) {
wt_len = strlen(opts.will_topic);
wm_len = strlen(opts.will_message);
opts.flags |= MG_MQTT_HAS_WILL;
}
if (opts.keep_alive == 0) {
opts.keep_alive = 60;
}
if (opts.flags & MG_MQTT_HAS_WILL) {
total_len += 2 + wt_len + 2 + wm_len;
}
if (opts.flags & MG_MQTT_HAS_USER_NAME) {
user_len = strlen(opts.user_name);
total_len += 2 + user_len;
}
if (opts.flags & MG_MQTT_HAS_PASSWORD) {
pw_len = strlen(opts.password);
total_len += 2 + pw_len;
}
mg_send_mqtt_header(nc, MG_MQTT_CMD_CONNECT, 0, total_len);
mg_send(nc, "\00\04MQTT\04", 7);
mg_send(nc, &opts.flags, 1);
rem_len += 1;
nlen = htons(opts.keep_alive);
mg_send(nc, &nlen, 2);
rem_len += 2;
netbytes = htons(opts.keep_alive);
mg_send(nc, &netbytes, 2);
hlen = strlen(client_id);
nlen = htons((uint16_t) hlen);
mg_send(nc, &nlen, 2);
mg_send(nc, client_id, hlen);
rem_len += 2 + hlen;
netbytes = htons(id_len);
mg_send(nc, &netbytes, 2);
mg_send(nc, client_id, id_len);
if (opts.flags & MG_MQTT_HAS_WILL) {
hlen = strlen(opts.will_topic);
nlen = htons((uint16_t) hlen);
mg_send(nc, &nlen, 2);
mg_send(nc, opts.will_topic, hlen);
rem_len += 2 + hlen;
netbytes = htons(wt_len);
mg_send(nc, &netbytes, 2);
mg_send(nc, opts.will_topic, wt_len);
hlen = strlen(opts.will_message);
nlen = htons((uint16_t) hlen);
mg_send(nc, &nlen, 2);
mg_send(nc, opts.will_message, hlen);
rem_len += 2 + hlen;
netbytes = htons(wm_len);
mg_send(nc, &netbytes, 2);
mg_send(nc, opts.will_message, wm_len);
}
if (opts.flags & MG_MQTT_HAS_USER_NAME) {
hlen = strlen(opts.user_name);
nlen = htons((uint16_t) hlen);
mg_send(nc, &nlen, 2);
mg_send(nc, opts.user_name, hlen);
rem_len += 2 + hlen;
netbytes = htons(user_len);
mg_send(nc, &netbytes, 2);
mg_send(nc, opts.user_name, user_len);
}
if (opts.flags & MG_MQTT_HAS_PASSWORD) {
hlen = strlen(opts.password);
nlen = htons((uint16_t) hlen);
mg_send(nc, &nlen, 2);
mg_send(nc, opts.password, hlen);
rem_len += 2 + hlen;
netbytes = htons(pw_len);
mg_send(nc, &netbytes, 2);
mg_send(nc, opts.password, pw_len);
}
mg_mqtt_prepend_header(nc, MG_MQTT_CMD_CONNECT, 0, rem_len);
if (pd != NULL) {
pd->keep_alive = opts.keep_alive;
}
......@@ -331,40 +333,52 @@ void mg_send_mqtt_handshake_opt(struct mg_connection *nc, const char *client_id,
void mg_mqtt_publish(struct mg_connection *nc, const char *topic,
uint16_t message_id, int flags, const void *data,
size_t len) {
size_t old_len = nc->send_mbuf.len;
uint16_t netbytes;
uint16_t topic_len = strlen(topic);
uint16_t topic_len = htons((uint16_t) strlen(topic));
uint16_t message_id_net = htons(message_id);
size_t total_len = 2 + topic_len + len;
if (MG_MQTT_GET_QOS(flags) > 0) {
total_len += 2;
}
mg_send_mqtt_header(nc, MG_MQTT_CMD_PUBLISH, flags, total_len);
netbytes = htons(topic_len);
mg_send(nc, &netbytes, 2);
mg_send(nc, topic, topic_len);
mg_send(nc, &topic_len, 2);
mg_send(nc, topic, strlen(topic));
if (MG_MQTT_GET_QOS(flags) > 0) {
mg_send(nc, &message_id_net, 2);
netbytes = htons(message_id);
mg_send(nc, &netbytes, 2);
}
mg_send(nc, data, len);
mg_mqtt_prepend_header(nc, MG_MQTT_CMD_PUBLISH, flags,
nc->send_mbuf.len - old_len);
mg_send(nc, data, len);
}
void mg_mqtt_subscribe(struct mg_connection *nc,
const struct mg_mqtt_topic_expression *topics,
size_t topics_len, uint16_t message_id) {
size_t old_len = nc->send_mbuf.len;
uint16_t message_id_n = htons(message_id);
uint16_t netbytes;
size_t i;
uint16_t topic_len;
size_t total_len = 2;
mg_send(nc, (char *) &message_id_n, 2);
for (i = 0; i < topics_len; i++) {
uint16_t topic_len_n = htons((uint16_t) strlen(topics[i].topic));
mg_send(nc, &topic_len_n, 2);
mg_send(nc, topics[i].topic, strlen(topics[i].topic));
mg_send(nc, &topics[i].qos, 1);
total_len += 2 + strlen(topics[i].topic) + 1;
}
mg_mqtt_prepend_header(nc, MG_MQTT_CMD_SUBSCRIBE, MG_MQTT_QOS(1),
nc->send_mbuf.len - old_len);
mg_send_mqtt_header(nc, MG_MQTT_CMD_SUBSCRIBE, MG_MQTT_QOS(1), total_len);
netbytes = htons(message_id);
mg_send(nc, (char *) &netbytes, 2);
for (i = 0; i < topics_len; i++) {
topic_len = strlen(topics[i].topic);
netbytes = htons(topic_len);
mg_send(nc, &netbytes, 2);
mg_send(nc, topics[i].topic, topic_len);
mg_send(nc, &topics[i].qos, 1);
}
}
int mg_mqtt_next_subscribe_topic(struct mg_mqtt_message *msg,
......@@ -384,27 +398,33 @@ int mg_mqtt_next_subscribe_topic(struct mg_mqtt_message *msg,
void mg_mqtt_unsubscribe(struct mg_connection *nc, char **topics,
size_t topics_len, uint16_t message_id) {
size_t old_len = nc->send_mbuf.len;
uint16_t message_id_n = htons(message_id);
uint16_t netbytes;
size_t i;
uint16_t topic_len;
size_t total_len = 2;
mg_send(nc, (char *) &message_id_n, 2);
for (i = 0; i < topics_len; i++) {
uint16_t topic_len_n = htons((uint16_t) strlen(topics[i]));
mg_send(nc, &topic_len_n, 2);
mg_send(nc, topics[i], strlen(topics[i]));
total_len += 2 + strlen(topics[i]);
}
mg_mqtt_prepend_header(nc, MG_MQTT_CMD_UNSUBSCRIBE, MG_MQTT_QOS(1),
nc->send_mbuf.len - old_len);
mg_send_mqtt_header(nc, MG_MQTT_CMD_UNSUBSCRIBE, MG_MQTT_QOS(1), total_len);
netbytes = htons(message_id);
mg_send(nc, (char *) &netbytes, 2);
for (i = 0; i < topics_len; i++) {
topic_len = strlen(topics[i]);
netbytes = htons(topic_len);
mg_send(nc, &netbytes, 2);
mg_send(nc, topics[i], topic_len);
}
}
void mg_mqtt_connack(struct mg_connection *nc, uint8_t return_code) {
uint8_t unused = 0;
mg_send_mqtt_header(nc, MG_MQTT_CMD_CONNACK, 0, 2);
mg_send(nc, &unused, 1);
mg_send(nc, &return_code, 1);
mg_mqtt_prepend_header(nc, MG_MQTT_CMD_CONNACK, 0, 2);
}
/*
......@@ -414,10 +434,13 @@ void mg_mqtt_connack(struct mg_connection *nc, uint8_t return_code) {
*/
static void mg_send_mqtt_short_command(struct mg_connection *nc, uint8_t cmd,
uint16_t message_id) {
uint16_t message_id_net = htons(message_id);
uint16_t netbytes;
uint8_t flags = (cmd == MG_MQTT_CMD_PUBREL ? 2 : 0);
mg_send(nc, &message_id_net, 2);
mg_mqtt_prepend_header(nc, cmd, flags, 2 /* len */);
mg_send_mqtt_header(nc, cmd, flags, 2 /* len */);
netbytes = htons(message_id);
mg_send(nc, &netbytes, 2);
}
void mg_mqtt_puback(struct mg_connection *nc, uint16_t message_id) {
......@@ -439,12 +462,16 @@ void mg_mqtt_pubcomp(struct mg_connection *nc, uint16_t message_id) {
void mg_mqtt_suback(struct mg_connection *nc, uint8_t *qoss, size_t qoss_len,
uint16_t message_id) {
size_t i;
uint16_t message_id_net = htons(message_id);
mg_send(nc, &message_id_net, 2);
uint16_t netbytes;
mg_send_mqtt_header(nc, MG_MQTT_CMD_SUBACK, MG_MQTT_QOS(1), 2 + qoss_len);
netbytes = htons(message_id);
mg_send(nc, &netbytes, 2);
for (i = 0; i < qoss_len; i++) {
mg_send(nc, &qoss[i], 1);
}
mg_mqtt_prepend_header(nc, MG_MQTT_CMD_SUBACK, MG_MQTT_QOS(1), 2 + qoss_len);
}
void mg_mqtt_unsuback(struct mg_connection *nc, uint16_t message_id) {
......@@ -452,15 +479,15 @@ void mg_mqtt_unsuback(struct mg_connection *nc, uint16_t message_id) {
}
void mg_mqtt_ping(struct mg_connection *nc) {
mg_mqtt_prepend_header(nc, MG_MQTT_CMD_PINGREQ, 0, 0);
mg_send_mqtt_header(nc, MG_MQTT_CMD_PINGREQ, 0, 0);
}
void mg_mqtt_pong(struct mg_connection *nc) {
mg_mqtt_prepend_header(nc, MG_MQTT_CMD_PINGRESP, 0, 0);
mg_send_mqtt_header(nc, MG_MQTT_CMD_PINGRESP, 0, 0);
}
void mg_mqtt_disconnect(struct mg_connection *nc) {
mg_mqtt_prepend_header(nc, MG_MQTT_CMD_DISCONNECT, 0, 0);
mg_send_mqtt_header(nc, MG_MQTT_CMD_DISCONNECT, 0, 0);
}
#endif /* MG_ENABLE_MQTT */
This diff is collapsed.
......@@ -54,10 +54,12 @@ struct mg_iface_vtable {
void (*connect_udp)(struct mg_connection *nc);
/* Send functions for TCP and UDP. Sent data is copied before return. */
void (*tcp_send)(struct mg_connection *nc, const void *buf, size_t len);
void (*udp_send)(struct mg_connection *nc, const void *buf, size_t len);
int (*tcp_send)(struct mg_connection *nc, const void *buf, size_t len);
int (*udp_send)(struct mg_connection *nc, const void *buf, size_t len);
void (*recved)(struct mg_connection *nc, size_t len);
int (*tcp_recv)(struct mg_connection *nc, void *buf, size_t len);
int (*udp_recv)(struct mg_connection *nc, void *buf, size_t len,
union socket_address *sa, size_t *sa_len);
/* Perform interface-related connection initialization. Return 1 on ok. */
int (*create_conn)(struct mg_connection *nc);
......@@ -98,19 +100,15 @@ void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa,
/* Callback invoked by connect methods. err = 0 -> ok, != 0 -> error. */
void mg_if_connect_cb(struct mg_connection *nc, int err);
/* Callback that reports that data has been put on the wire. */
void mg_if_sent_cb(struct mg_connection *nc, int num_sent);
/*
* Receive callback.
* if `own` is true, buf must be heap-allocated and ownership is transferred
* to the core.
* Core will acknowledge consumption by calling iface::recved.
* Callback that tells the core that data can be received.
* Core will use tcp/udp_recv to retrieve the data.
*/
void mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len, int own);
void mg_if_can_recv_cb(struct mg_connection *nc);
void mg_if_can_send_cb(struct mg_connection *nc);
/*
* Receive callback.
* buf must be heap-allocated and ownership is transferred to the core.
* Core will acknowledge consumption by calling iface::recved.
*/
void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,
union socket_address *sa, size_t sa_len);
......@@ -118,10 +116,7 @@ void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,
/* void mg_if_close_conn(struct mg_connection *nc); */
/* Deliver a POLL event to the connection. */
void mg_if_poll(struct mg_connection *nc, time_t now);
/* Deliver a TIMER event to the connection. */
void mg_if_timer(struct mg_connection *c, double now);
int mg_if_poll(struct mg_connection *nc, double now);
#ifdef __cplusplus
}
......
This diff is collapsed.
......@@ -9,18 +9,35 @@ struct socksdata {
char *proxy_addr; /* HOST:PORT of the socks5 proxy server */
struct mg_connection *s; /* Respective connection to the server */
struct mg_connection *c; /* Connection to the client */
struct mbuf tmp; /* Temporary buffer for sent data */
};
static void socks_if_disband(struct socksdata *d) {
LOG(LL_DEBUG, ("disbanding proxy %p %p", d->c, d->s));
if (d->c) d->c->flags |= MG_F_SEND_AND_CLOSE;
if (d->s) d->s->flags |= MG_F_SEND_AND_CLOSE;
d->c = d->s = NULL;
if (d->c) {
d->c->flags |= MG_F_SEND_AND_CLOSE;
d->c->user_data = NULL;
d->c = NULL;
}
if (d->s) {
d->s->flags |= MG_F_SEND_AND_CLOSE;
d->s->user_data = NULL;
d->s = NULL;
}
}
static void socks_if_relay(struct mg_connection *s) {
struct socksdata *d = (struct socksdata *) s->user_data;
if (d == NULL || d->c == NULL || !(s->flags & MG_SOCKS_CONNECT_DONE) ||
d->s == NULL) {
return;
}
if (s->recv_mbuf.len > 0) mg_if_can_recv_cb(d->c);
if (d->c->send_mbuf.len > 0 && s->send_mbuf.len == 0) mg_if_can_send_cb(d->c);
}
static void socks_if_handler(struct mg_connection *c, int ev, void *ev_data) {
struct socksdata *d = (struct socksdata *) c->user_data;
if (d == NULL) return;
if (ev == MG_EV_CONNECT) {
int res = *(int *) ev_data;
if (res == 0) {
......@@ -53,6 +70,7 @@ static void socks_if_handler(struct mg_connection *c, int ev, void *ev_data) {
memcpy(buf + 4, &d->c->sa.sin.sin_addr, 4);
memcpy(buf + 8, &d->c->sa.sin.sin_port, 2);
mg_send(c, buf, sizeof(buf));
LOG(LL_DEBUG, ("%p Sent connect request", c));
}
/* Process connect request */
if ((c->flags & MG_SOCKS_HANDSHAKE_DONE) &&
......@@ -65,17 +83,12 @@ static void socks_if_handler(struct mg_connection *c, int ev, void *ev_data) {
}
mbuf_remove(&c->recv_mbuf, 10);
c->flags |= MG_SOCKS_CONNECT_DONE;
/* Connected. Move sent data from client, if any, to server */
if (d->s && d->c) {
mbuf_append(&d->s->send_mbuf, d->tmp.buf, d->tmp.len);
mbuf_free(&d->tmp);
}
}
/* All flags are set, we're in relay mode */
if ((c->flags & MG_SOCKS_CONNECT_DONE) && d->c && d->s) {
mbuf_append(&d->c->recv_mbuf, d->s->recv_mbuf.buf, d->s->recv_mbuf.len);
mbuf_remove(&d->s->recv_mbuf, d->s->recv_mbuf.len);
LOG(LL_DEBUG, ("%p Connect done %p", c, d->c));
mg_if_connect_cb(d->c, 0);
}
socks_if_relay(c);
} else if (ev == MG_EV_SEND || ev == MG_EV_POLL) {
socks_if_relay(c);
}
}
......@@ -85,7 +98,7 @@ static void mg_socks_if_connect_tcp(struct mg_connection *c,
d->c = c;
d->s = mg_connect(c->mgr, d->proxy_addr, socks_if_handler);
d->s->user_data = d;
LOG(LL_DEBUG, ("%p %s", c, d->proxy_addr));
LOG(LL_DEBUG, ("%p %s %p %p", c, d->proxy_addr, d, d->s));
(void) sa;
}
......@@ -107,29 +120,44 @@ static int mg_socks_if_listen_udp(struct mg_connection *c,
return -1;
}
static void mg_socks_if_tcp_send(struct mg_connection *c, const void *buf,
static int mg_socks_if_tcp_send(struct mg_connection *c, const void *buf,
size_t len) {
int res;
struct socksdata *d = (struct socksdata *) c->iface->data;
LOG(LL_DEBUG, ("%p -> %p %d %d", c, buf, (int) len, (int) c->send_mbuf.len));
if (d && d->s && d->s->flags & MG_SOCKS_CONNECT_DONE) {
mbuf_append(&d->s->send_mbuf, d->tmp.buf, d->tmp.len);
mbuf_append(&d->s->send_mbuf, buf, len);
mbuf_free(&d->tmp);
} else {
mbuf_append(&d->tmp, buf, len);
}
if (d->s == NULL) return -1;
res = (int) mbuf_append(&d->s->send_mbuf, buf, len);
DBG(("%p -> %d -> %p", c, res, d->s));
return res;
}
static void mg_socks_if_udp_send(struct mg_connection *c, const void *buf,
static int mg_socks_if_udp_send(struct mg_connection *c, const void *buf,
size_t len) {
(void) c;
(void) buf;
(void) len;
return -1;
}
static void mg_socks_if_recved(struct mg_connection *c, size_t len) {
int mg_socks_if_tcp_recv(struct mg_connection *c, void *buf, size_t len) {
struct socksdata *d = (struct socksdata *) c->iface->data;
if (d->s == NULL) return -1;
if (len > d->s->recv_mbuf.len) len = d->s->recv_mbuf.len;
if (len > 0) {
memcpy(buf, d->s->recv_mbuf.buf, len);
mbuf_remove(&d->s->recv_mbuf, len);
}
DBG(("%p <- %d <- %p", c, (int) len, d->s));
return len;
}
int mg_socks_if_udp_recv(struct mg_connection *c, void *buf, size_t len,
union socket_address *sa, size_t *sa_len) {
(void) c;
(void) buf;
(void) len;
(void) sa;
(void) sa_len;
return -1;
}
static int mg_socks_if_create_conn(struct mg_connection *c) {
......@@ -158,7 +186,6 @@ static void mg_socks_if_free(struct mg_iface *iface) {
LOG(LL_DEBUG, ("%p", iface));
if (d != NULL) {
socks_if_disband(d);
mbuf_free(&d->tmp);
MG_FREE(d->proxy_addr);
MG_FREE(d);
iface->data = NULL;
......@@ -194,9 +221,10 @@ const struct mg_iface_vtable mg_socks_iface_vtable = {
mg_socks_if_poll, mg_socks_if_listen_tcp,
mg_socks_if_listen_udp, mg_socks_if_connect_tcp,
mg_socks_if_connect_udp, mg_socks_if_tcp_send,
mg_socks_if_udp_send, mg_socks_if_recved,
mg_socks_if_create_conn, mg_socks_if_destroy_conn,
mg_socks_if_sock_set, mg_socks_if_get_conn_addr,
mg_socks_if_udp_send, mg_socks_if_tcp_recv,
mg_socks_if_udp_recv, mg_socks_if_create_conn,
mg_socks_if_destroy_conn, mg_socks_if_sock_set,
mg_socks_if_get_conn_addr,
};
struct mg_iface *mg_socks_mk_iface(struct mg_mgr *mgr, const char *proxy_addr) {
......
......@@ -148,7 +148,6 @@ static void mg_resolve_async_eh(struct mg_connection *nc, int ev,
time_t now = (time_t) mg_time();
struct mg_resolve_async_request *req;
struct mg_dns_message *msg;
int first = 0;
#if !MG_ENABLE_CALLBACK_USERDATA
void *user_data = nc->user_data;
#endif
......@@ -162,17 +161,16 @@ static void mg_resolve_async_eh(struct mg_connection *nc, int ev,
}
switch (ev) {
case MG_EV_CONNECT:
/* don't depend on timer not being at epoch for sending out first req */
first = 1;
/* fallthrough */
case MG_EV_POLL:
if (req->retries > req->max_retries) {
req->err = MG_RESOLVE_EXCEEDED_RETRY_COUNT;
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
break;
}
if (first || now - req->last_time >= req->timeout) {
if (nc->flags & MG_F_CONNECTING) break;
/* fallthrough */
case MG_EV_CONNECT:
if (req->retries == 0 || now - req->last_time >= req->timeout) {
mg_send_dns_query(nc, req->name, req->query);
req->last_time = now;
req->retries++;
......
This diff is collapsed.
......@@ -10,6 +10,9 @@
#endif
#include <openssl/ssl.h>
#ifndef KR_VERSION
#include <openssl/tls1.h>
#endif
struct mg_ssl_if_ctx {
SSL *ssl;
......@@ -94,14 +97,6 @@ enum mg_ssl_if_result mg_ssl_if_conn_init(
return MG_SSL_ERROR;
}
if (params->server_name != NULL) {
#ifdef KR_VERSION
SSL_CTX_kr_set_verify_name(ctx->ssl_ctx, params->server_name);
#else
/* TODO(rojer): Implement server name verification on OpenSSL. */
#endif
}
if (mg_set_cipher_list(ctx->ssl_ctx, params->cipher_suites) != MG_SSL_OK) {
MG_SET_PTRPTR(err_msg, "Invalid cipher suite list");
return MG_SSL_ERROR;
......@@ -120,6 +115,14 @@ enum mg_ssl_if_result mg_ssl_if_conn_init(
return MG_SSL_ERROR;
}
if (params->server_name != NULL) {
#ifdef KR_VERSION
SSL_CTX_kr_set_verify_name(ctx->ssl_ctx, params->server_name);
#else
SSL_set_tlsext_host_name(ctx->ssl, params->server_name);
#endif
}
nc->flags |= MG_F_SSL;
return MG_SSL_OK;
......
......@@ -144,7 +144,7 @@ int mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,
goto cleanup;
}
#else
if (inet_ntop(AF_INET, (void *) &sa->sin.sin_addr, buf, len - 1) == NULL) {
if (inet_ntop(AF_INET, (void *) &sa->sin.sin_addr, buf, len) == NULL) {
goto cleanup;
}
#endif
......@@ -313,17 +313,21 @@ void mg_basic_auth_header(const struct mg_str user, const struct mg_str pass,
mbuf_append(buf, header_suffix, strlen(header_suffix));
}
struct mg_str mg_url_encode(const struct mg_str src) {
static const char *dont_escape = "._-$,;~()/";
static const char *hex = "0123456789abcdef";
struct mg_str mg_url_encode_opt(const struct mg_str src,
const struct mg_str safe, unsigned int flags) {
const char *hex =
(flags & MG_URL_ENCODE_F_UPPERCASE_HEX ? "0123456789ABCDEF"
: "0123456789abcdef");
size_t i = 0;
struct mbuf mb;
mbuf_init(&mb, src.len);
for (i = 0; i < src.len; i++) {
const unsigned char c = *((const unsigned char *) src.p + i);
if (isalnum(c) || strchr(dont_escape, c) != NULL) {
if (isalnum(c) || mg_strchr(safe, c) != NULL) {
mbuf_append(&mb, &c, 1);
} else if (c == ' ' && (flags & MG_URL_ENCODE_F_SPACE_AS_PLUS)) {
mbuf_append(&mb, "+", 1);
} else {
mbuf_append(&mb, "%", 1);
mbuf_append(&mb, &hex[c >> 4], 1);
......@@ -334,3 +338,7 @@ struct mg_str mg_url_encode(const struct mg_str src) {
mbuf_trim(&mb);
return mg_mk_str_n(mb.buf, mb.len - 1);
}
struct mg_str mg_url_encode(const struct mg_str src) {
return mg_url_encode_opt(src, mg_mk_str("._-$,;~()/"), 0);
}
......@@ -196,10 +196,17 @@ void mg_basic_auth_header(const struct mg_str user, const struct mg_str pass,
/*
* URL-escape the specified string.
* All non-printable characters are escaped, plus `._-$,;~()/`.
* All characters acept letters, numbers and characters listed in
* `safe` are escaped. If `hex_upper`is true, `A-F` are used for hex digits.
* Input need not be NUL-terminated, but the returned string is.
* Returned string is heap-allocated and must be free()'d.
*/
#define MG_URL_ENCODE_F_SPACE_AS_PLUS (1 << 0)
#define MG_URL_ENCODE_F_UPPERCASE_HEX (1 << 1)
struct mg_str mg_url_encode_opt(const struct mg_str src,
const struct mg_str safe, unsigned int flags);
/* Same as `mg_url_encode_opt(src, "._-$,;~()/", 0)`. */
struct mg_str mg_url_encode(const struct mg_str src);
#ifdef __cplusplus
......
......@@ -28,7 +28,7 @@
# OSX clang doesn't build ASAN. Use brew:
# $ brew tap homebrew/versions
# $ brew install llvm36 --with-clang --with-asan
CLANG:=clang-3.6
CLANG:=clang
PEDANTIC=$(shell gcc --version 2>/dev/null | grep -q clang && echo -pedantic)
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment