Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 44 additions & 18 deletions src/http/httpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ static const char *http_status_text(int status_code) {
}

int httpd_register_handler(struct httpd *httpd, const char *path, int (*handler)(struct httpd *httpd, struct http_client *hc, struct http_request *req)) {
for (int i = 0; i < HTTPD_MAX_URLS; i++) {
if (httpd->urls[i].handler == NULL) {
int i;
for (i = 0; i < HTTPD_MAX_URLS; i++) {
if (httpd->urls[i].path[0] == '\0') {
/* Copy path and guarantee null termination */
strncpy(httpd->urls[i].path, path, HTTP_PATH_LEN);
httpd->urls[i].path[HTTP_PATH_LEN-1] = '\0';
Expand All @@ -84,8 +85,9 @@ int httpd_register_handler(struct httpd *httpd, const char *path, int (*handler)
}

int httpd_register_static_page(struct httpd *httpd, const char *path, const char *content) {
for (int i = 0; i < HTTPD_MAX_URLS; i++) {
if (httpd->urls[i].handler == NULL) {
int i;
for (i = 0; i < HTTPD_MAX_URLS; i++) {
if (httpd->urls[i].path[0] == '\0') {
/* Copy path and guarantee null termination */
strncpy(httpd->urls[i].path, path, HTTP_PATH_LEN);
httpd->urls[i].path[HTTP_PATH_LEN-1] = '\0';
Expand Down Expand Up @@ -181,7 +183,7 @@ static void http_close_client(struct http_client *hc)
}

void http_send_response_chunk(struct http_client *hc, const void *chunk, size_t len) {
char txt_chunk[8];
char txt_chunk[20];
memset(txt_chunk, 0, sizeof(txt_chunk));
if (!hc)
return;
Expand Down Expand Up @@ -290,7 +292,7 @@ int http_url_encode(char *buf, size_t len, size_t max_len) {
if (q) {
if (len >= max_len)
return -1; /* No space for the null terminator */
q[len] = '\0';
buf[len] = '\0';
}
return len;
}
Expand Down Expand Up @@ -319,7 +321,10 @@ static int parse_http_request(struct http_client *hc, uint8_t *buf, size_t len)
char *p = (char *) buf;
char *end = p + len;
char *q;
char *query_start = NULL;
size_t n;
size_t path_len;
size_t query_len;
int ret;
int decoded_len;
long content_length = -1; /* -1: no Content-Length header seen */
Expand All @@ -343,26 +348,40 @@ static int parse_http_request(struct http_client *hc, uint8_t *buf, size_t len)
if (!q)
goto bad_request;
n = q - p;
if (n >= sizeof(req.path))
/* Split the request target into path and optional query (on '?'). */
query_start = memchr(p, '?', n);
if (query_start != NULL) {
path_len = (size_t)(query_start - p);
query_len = n - path_len - 1U;
} else {
path_len = n;
query_len = 0;
}
if (path_len >= sizeof(req.path))
goto bad_request;
memcpy(req.path, p, n);
req.path[n] = '\0';
decoded_len = http_url_decode(req.path, n);
memcpy(req.path, p, path_len);
req.path[path_len] = '\0';
decoded_len = http_url_decode(req.path, path_len);
if (decoded_len < 0)
goto bad_request;
req.path[decoded_len] = '\0';
if (memchr(req.path, '\r', (size_t)decoded_len) ||
memchr(req.path, '\n', (size_t)decoded_len))
goto bad_request;
if (query_start != NULL) {
if (query_len >= sizeof(req.query))
goto bad_request;
if (memchr(query_start + 1, '\r', query_len) ||
memchr(query_start + 1, '\n', query_len))
goto bad_request;
memcpy(req.query, query_start + 1, query_len);
req.query[query_len] = '\0';
}
/* Skip the HTTP version token; only its CRLF framing matters here. */
p = q + 1;
q = strchr(p, '\r');
if (!q)
goto bad_request;
n = q - p;
if (n >= sizeof(req.query))
goto bad_request;
memcpy(req.query, p, n);
req.query[n] = '\0';
p = q + 2;

/* Parse the headers */
Expand Down Expand Up @@ -466,7 +485,7 @@ static void http_recv_cb(int sd, uint16_t event, void *arg) {
if (!hc) return;
(void) event;
if (hc->ssl) {
ret = wolfSSL_read(hc->ssl, buf, sizeof(buf));
ret = wolfSSL_read(hc->ssl, buf, sizeof(buf) - 1);
if (ret < 0) {
if (wolfSSL_get_error(hc->ssl, ret) == WOLFSSL_ERROR_WANT_READ) {
return;
Expand All @@ -475,12 +494,14 @@ static void http_recv_cb(int sd, uint16_t event, void *arg) {
}
}
} else {
ret = wolfIP_sock_recv(hc->httpd->ipstack, sd, buf, sizeof(buf), 0);
ret = wolfIP_sock_recv(hc->httpd->ipstack, sd, buf, sizeof(buf) - 1, 0);
if (ret == -WOLFIP_EAGAIN)
return;
}
if (ret <= 0)
goto fail_close;
/* The parser uses strchr/strstr, so terminate the bounded read. */
buf[ret] = '\0';
parse_r = parse_http_request(hc, buf, ret);
if (parse_r < 0)
goto fail_close;
Expand All @@ -503,11 +524,13 @@ static void http_accept_cb(int sd, uint16_t event, void *arg) {
struct wolfIP_sockaddr_in addr;
socklen_t addr_len = sizeof(struct wolfIP_sockaddr_in);
int client_sd = wolfIP_sock_accept(httpd->ipstack, sd, (struct wolfIP_sockaddr *) &addr, &addr_len);
int i;
int assigned = 0;
if (client_sd < 0) {
return;
}
(void) event;
for (int i = 0; i < HTTPD_MAX_CLIENTS; i++) {
for (i = 0; i < HTTPD_MAX_CLIENTS; i++) {
if (httpd->clients[i].client_sd == 0) {
httpd->clients[i].client_sd = client_sd;
httpd->clients[i].httpd = httpd;
Expand All @@ -524,9 +547,12 @@ static void http_accept_cb(int sd, uint16_t event, void *arg) {
}
}
wolfIP_register_callback(httpd->ipstack, client_sd, http_recv_cb, &httpd->clients[i]);
assigned = 1;
break;
}
}
if (!assigned)
wolfIP_sock_close(httpd->ipstack, client_sd);
}

/* Extra utility to extract requests arguments */
Expand Down
14 changes: 3 additions & 11 deletions src/port/posix/bsd_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,6 @@ int wolfIP_sock_recvmsg(struct wolfIP *ipstack, int sockfd, struct msghdr *msg,
uint8_t stack_buf[WOLFIP_IOV_STACK_BUF] = {0};
uint8_t *heap_buf = NULL;
uint8_t *buf = NULL;
struct pollfd pfd;

if (wolfip_calc_msghdr_len(msg, &total_len) < 0)
return -WOLFIP_EINVAL;
Expand All @@ -1029,16 +1028,9 @@ int wolfIP_sock_recvmsg(struct wolfIP *ipstack, int sockfd, struct msghdr *msg,
}
}

pfd.fd = sockfd;
pfd.events = POLLIN;
pfd.revents = 0;
while (1) {
ret = wolfIP_sock_recvfrom(ipstack, sockfd, buf ? buf : msg->msg_iov[0].iov_base,
total_len, flags, src, src ? &addrlen : NULL);
if (ret != -WOLFIP_EAGAIN)
break;
(void)wolfIP_sock_poll(ipstack, &pfd, 1, -1);
}
/* Return EAGAIN to the caller; the wrapper handles non-blocking/timeout. */
ret = wolfIP_sock_recvfrom(ipstack, sockfd, buf ? buf : msg->msg_iov[0].iov_base,
total_len, flags, src, src ? &addrlen : NULL);
if (ret > 0 && msg->msg_iovlen > 1 && buf) {
wolfip_scatter_iov(msg, buf, (size_t)ret);
}
Expand Down
10 changes: 7 additions & 3 deletions src/port/raspberry-pico-usb-server/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ extern char MOTD[];
static struct wolfIP *IPStack = NULL;

/* Two static buffers for RX frames from USB host */
uint8_t tusb_net_rxbuf[LINK_MTU][2];
uint8_t tusb_net_rxbuf[2][LINK_MTU];
uint8_t tusb_net_rxbuf_used[2] = {0, 0};

/* Two static buffers for TX frames to USB host */
uint8_t tusb_net_txbuf[LINK_MTU][2];
uint8_t tusb_net_txbuf[2][LINK_MTU];
uint16_t tusb_net_txbuf_sz[2] = {0, 0};

/* Fixed mac-address for the raspberry side of the link.
Expand All @@ -81,6 +81,8 @@ static int ll_usb_send(struct wolfIP_ll_dev *dev, void *frame, uint32_t sz) {
uint16_t sz16 = (uint16_t)sz;
uint32_t i;
(void) dev;
if (sz > LINK_MTU)
return 0;
board_led_on();
for (;;) {
if (!tud_ready()) {
Expand Down Expand Up @@ -111,7 +113,7 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) {
(void) ref;
(void) arg;
memcpy(dst, ref, arg);
if (ref == tusb_net_rxbuf[0])
if (ref == tusb_net_txbuf[0])
tusb_net_txbuf_sz[0] = 0;
else if (ref == tusb_net_txbuf[1])
tusb_net_txbuf_sz[1] = 0;
Expand All @@ -127,6 +129,8 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) {
static void tusb_net_push_rx(const uint8_t *src, uint16_t size) {
uint8_t *dst = NULL;
int i;
if (size > LINK_MTU)
return;
for (i = 0; i < 2; i++) {
if (!tusb_net_rxbuf_used[i]) {
dst = tusb_net_rxbuf[i];
Expand Down
9 changes: 6 additions & 3 deletions src/port/wolfmqtt_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ static struct wolfmqtt_io_desc *io_desc_alloc(void)
if (!io_descs[i].in_use) {
io_descs[i].in_use = 1;
io_descs[i].connected = 0;
io_descs[i].fd = -1;
return &io_descs[i];
}
}
Expand Down Expand Up @@ -75,10 +76,12 @@ static int wolfmqtt_net_connect(void *context, const char *host, word16 port,
return MQTT_CODE_ERROR_BAD_ARG;
}

/* Create TCP socket */
desc->fd = wolfIP_sock_socket(desc->stack, AF_INET, IPSTACK_SOCK_STREAM, 0);
/* Create the socket only on the first attempt; async retries reuse it. */
if (desc->fd < 0) {
return MQTT_CODE_ERROR_NETWORK;
desc->fd = wolfIP_sock_socket(desc->stack, AF_INET, IPSTACK_SOCK_STREAM, 0);
if (desc->fd < 0) {
return MQTT_CODE_ERROR_NETWORK;
}
}

/* Set up address */
Expand Down
9 changes: 7 additions & 2 deletions src/tftp/wolftftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,17 @@ static int wolftftp_parse_u32(const char *value, uint32_t max_value,
uint32_t *out)
{
uint32_t v = 0;
uint32_t digit;

if (value == NULL || out == NULL || *value == '\0')
return -1;
while (*value != '\0') {
if (*value < '0' || *value > '9')
return -1;
v = (v * 10U) + (uint32_t)(*value - '0');
digit = (uint32_t)(*value - '0');
if (v > (0xFFFFFFFFU - digit) / 10U)
return -1;
v = (v * 10U) + digit;
if (v > max_value)
return -1;
value++;
Expand Down Expand Up @@ -335,7 +339,8 @@ static int wolftftp_parse_request(const uint8_t *buf, uint16_t len,
return WOLFTFTP_ERR_PACKET;
p += slen + 1U;
slen = wolftftp_strnlen_local(p, (size_t)(buf + len - (const uint8_t *)p));
if (slen == 0 || wolftftp_stricmp_local(p, "octet") != 0)
if (slen == 0 || (const uint8_t *)(p + slen) >= buf + len ||
wolftftp_stricmp_local(p, "octet") != 0)
return WOLFTFTP_ERR_UNSUPPORTED;
p += slen + 1U;

Expand Down
Loading