Merge pull request #8250 from kb2ma/gcoap/remote_in_request
net/gcoap: Track remote endpoint for all requests
This commit is contained in:
commit
c24e87e47d
@ -435,7 +435,6 @@ typedef void (*gcoap_resp_handler_t)(unsigned req_state, coap_pkt_t* pdu,
|
|||||||
* @brief Extends request memo for resending a confirmable request.
|
* @brief Extends request memo for resending a confirmable request.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
sock_udp_ep_t remote_ep; /**< Remote endpoint */
|
|
||||||
uint8_t *pdu_buf; /**< Buffer containing the PDU */
|
uint8_t *pdu_buf; /**< Buffer containing the PDU */
|
||||||
size_t pdu_len; /**< Length of pdu_buf */
|
size_t pdu_len; /**< Length of pdu_buf */
|
||||||
} gcoap_resend_t;
|
} gcoap_resend_t;
|
||||||
@ -453,6 +452,7 @@ typedef struct {
|
|||||||
gcoap_resend_t data; /**< Endpoint and PDU buffer, for resend */
|
gcoap_resend_t data; /**< Endpoint and PDU buffer, for resend */
|
||||||
} msg; /**< Request message data; if confirmable,
|
} msg; /**< Request message data; if confirmable,
|
||||||
supports resending message */
|
supports resending message */
|
||||||
|
sock_udp_ep_t remote_ep; /**< Remote endpoint */
|
||||||
gcoap_resp_handler_t resp_handler; /**< Callback for the response */
|
gcoap_resp_handler_t resp_handler; /**< Callback for the response */
|
||||||
xtimer_t response_timer; /**< Limits wait for response */
|
xtimer_t response_timer; /**< Limits wait for response */
|
||||||
msg_t timeout_msg; /**< For response timer */
|
msg_t timeout_msg; /**< For response timer */
|
||||||
|
|||||||
@ -35,7 +35,9 @@ static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
|
|||||||
sock_udp_ep_t *remote);
|
sock_udp_ep_t *remote);
|
||||||
static ssize_t _finish_pdu(coap_pkt_t *pdu, uint8_t *buf, size_t len);
|
static ssize_t _finish_pdu(coap_pkt_t *pdu, uint8_t *buf, size_t len);
|
||||||
static void _expire_request(gcoap_request_memo_t *memo);
|
static void _expire_request(gcoap_request_memo_t *memo);
|
||||||
static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *pdu);
|
static bool _endpoints_equal(const sock_udp_ep_t *ep1, const sock_udp_ep_t *ep2);
|
||||||
|
static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *pdu,
|
||||||
|
const sock_udp_ep_t *remote);
|
||||||
static void _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
|
static void _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
|
||||||
gcoap_listener_t **listener_ptr);
|
gcoap_listener_t **listener_ptr);
|
||||||
static int _find_observer(sock_udp_ep_t **observer, sock_udp_ep_t *remote);
|
static int _find_observer(sock_udp_ep_t **observer, sock_udp_ep_t *remote);
|
||||||
@ -155,7 +157,7 @@ static void _listen(sock_udp_t *sock)
|
|||||||
|
|
||||||
/* incoming response */
|
/* incoming response */
|
||||||
else {
|
else {
|
||||||
_find_req_memo(&memo, &pdu);
|
_find_req_memo(&memo, &pdu, &remote);
|
||||||
if (memo) {
|
if (memo) {
|
||||||
xtimer_remove(&memo->response_timer);
|
xtimer_remove(&memo->response_timer);
|
||||||
memo->state = GCOAP_MEMO_RESP;
|
memo->state = GCOAP_MEMO_RESP;
|
||||||
@ -328,12 +330,14 @@ static ssize_t _finish_pdu(coap_pkt_t *pdu, uint8_t *buf, size_t len)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Finds the memo for an outstanding request within the _coap_state.open_reqs
|
* Finds the memo for an outstanding request within the _coap_state.open_reqs
|
||||||
* array. Matches on token.
|
* array. Matches on remote endpoint and token.
|
||||||
*
|
*
|
||||||
* memo_ptr[out] -- Registered request memo, or NULL if not found
|
* memo_ptr[out] -- Registered request memo, or NULL if not found
|
||||||
* src_pdu[in] -- PDU for token to match
|
* src_pdu[in] -- PDU for token to match
|
||||||
|
* remote[in] -- Remote endpoint to match
|
||||||
*/
|
*/
|
||||||
static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *src_pdu)
|
static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *src_pdu,
|
||||||
|
const sock_udp_ep_t *remote)
|
||||||
{
|
{
|
||||||
*memo_ptr = NULL;
|
*memo_ptr = NULL;
|
||||||
/* no need to initialize struct; we only care about buffer contents below */
|
/* no need to initialize struct; we only care about buffer contents below */
|
||||||
@ -355,7 +359,8 @@ static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *src_pdu)
|
|||||||
|
|
||||||
if (coap_get_token_len(memo_pdu) == cmplen) {
|
if (coap_get_token_len(memo_pdu) == cmplen) {
|
||||||
memo_pdu->token = &memo_pdu->hdr->data[0];
|
memo_pdu->token = &memo_pdu->hdr->data[0];
|
||||||
if (memcmp(src_pdu->token, memo_pdu->token, cmplen) == 0) {
|
if ((memcmp(src_pdu->token, memo_pdu->token, cmplen) == 0)
|
||||||
|
&& _endpoints_equal(&memo->remote_ep, remote)) {
|
||||||
*memo_ptr = memo;
|
*memo_ptr = memo;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -461,6 +466,24 @@ static ssize_t _write_options(coap_pkt_t *pdu, uint8_t *buf, size_t len)
|
|||||||
return bufpos - buf;
|
return bufpos - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool _endpoints_equal(const sock_udp_ep_t *ep1, const sock_udp_ep_t *ep2)
|
||||||
|
{
|
||||||
|
if (ep1->family != ep2->family) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ep1->port != ep2->port) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ep1->family) {
|
||||||
|
case AF_INET6:
|
||||||
|
return memcmp(&ep1->addr.ipv6[0], &ep2->addr.ipv6[0], 16) == 0;
|
||||||
|
case AF_INET:
|
||||||
|
return ep1->addr.ipv4_u32 == ep2->addr.ipv4_u32;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find registered observer for a remote address and port.
|
* Find registered observer for a remote address and port.
|
||||||
*
|
*
|
||||||
@ -475,23 +498,11 @@ static int _find_observer(sock_udp_ep_t **observer, sock_udp_ep_t *remote)
|
|||||||
int empty_slot = -1;
|
int empty_slot = -1;
|
||||||
*observer = NULL;
|
*observer = NULL;
|
||||||
for (unsigned i = 0; i < GCOAP_OBS_CLIENTS_MAX; i++) {
|
for (unsigned i = 0; i < GCOAP_OBS_CLIENTS_MAX; i++) {
|
||||||
unsigned cmplen = 0;
|
|
||||||
|
|
||||||
if (_coap_state.observers[i].family == AF_UNSPEC) {
|
if (_coap_state.observers[i].family == AF_UNSPEC) {
|
||||||
cmplen = 0;
|
|
||||||
empty_slot = i;
|
empty_slot = i;
|
||||||
}
|
}
|
||||||
else if (_coap_state.observers[i].family == AF_INET6) {
|
else if (_endpoints_equal(&_coap_state.observers[i], remote)) {
|
||||||
cmplen = 16;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cmplen = 4;
|
|
||||||
}
|
|
||||||
if (cmplen &&
|
|
||||||
memcmp(&_coap_state.observers[i].addr.ipv6[0], &remote->addr.ipv6[0],
|
|
||||||
cmplen) == 0
|
|
||||||
&& _coap_state.observers[i].port == remote->port) {
|
|
||||||
|
|
||||||
*observer = &_coap_state.observers[i];
|
*observer = &_coap_state.observers[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -688,6 +699,7 @@ size_t gcoap_req_send2(const uint8_t *buf, size_t len,
|
|||||||
if (memo) {
|
if (memo) {
|
||||||
memo->send_limit = GCOAP_SEND_LIMIT_NON;
|
memo->send_limit = GCOAP_SEND_LIMIT_NON;
|
||||||
memcpy(&memo->msg.hdr_buf[0], buf, GCOAP_HEADER_MAXLEN);
|
memcpy(&memo->msg.hdr_buf[0], buf, GCOAP_HEADER_MAXLEN);
|
||||||
|
memcpy(&memo->remote_ep, remote, sizeof(sock_udp_ep_t));
|
||||||
memo->resp_handler = resp_handler;
|
memo->resp_handler = resp_handler;
|
||||||
|
|
||||||
size_t res = sock_udp_send(&_sock, buf, len, remote);
|
size_t res = sock_udp_send(&_sock, buf, len, remote);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user