diff --git a/coap_config.h.contiki b/coap_config.h.contiki index 87fdbf07..01f149e1 100644 --- a/coap_config.h.contiki +++ b/coap_config.h.contiki @@ -11,7 +11,8 @@ #define PACKAGE_STRING "libcoap" #define PACKAGE_NAME "libcoap" -#define COAP_MAX_PDU_SIZE 64 +#define COAP_DEFAULT_PDU_SIZE 64 +#define COAP_RXBUFFER_SIZE 64 /** Number of resources that can be handled by a CoAP server in addition to * @c /.well-known/core */ @@ -30,6 +31,11 @@ */ #define COAP_PDU_MAXCNT 4 +/** + * Maximum number of sessions. + */ +#define COAP_MAX_SESSIONS 2 + /** * Maximum number of subscriptions. Every additional subscriber costs * 36 B. @@ -81,8 +87,10 @@ /* Need to set the byte order for TMote Sky explicitely */ #define BYTE_ORDER UIP_LITTLE_ENDIAN -#undef COAP_MAX_PDU_SIZE -#define COAP_MAX_PDU_SIZE 100 +#undef COAP_DEFAULT_PDU_SIZE +#undef COAP_RXBUFFER_SIZE +#define COAP_DEFAULT_PDU_SIZE 100 +#define COAP_RXBUFFER_SIZE 100 #define COAP_MAX_BLOCK_SZX 2 @@ -95,8 +103,10 @@ typedef void FILE; #endif /* defined(TMOTE_SKY) */ #ifdef CONTIKI_TARGET_MINIMAL_NET -#undef COAP_MAX_PDU_SIZE -#define COAP_MAX_PDU_SIZE 1400 +#undef COAP_DEFAULT_PDU_SIZE +#undef COAP_RXBUFFER_SIZE +#define COAP_DEFAULT_PDU_SIZE 1152 +#define COAP_RXBUFFER_SIZE 1472 #define HAVE_ASSERT_H 1 #define HAVE_VPRINTF 1 #define HAVE_SYS_TYPES_H 1 @@ -104,8 +114,10 @@ typedef void FILE; #ifdef CONTIKI_TARGET_CC2538DK #define BYTE_ORDER UIP_LITTLE_ENDIAN -#undef COAP_MAX_PDU_SIZE -#define COAP_MAX_PDU_SIZE 100 +#undef COAP_DEFAULT_PDU_SIZE +#undef COAP_RXBUFFER_SIZE +#define COAP_DEFAULT_PDU_SIZE 100 +#define COAP_RXBUFFER_SIZE 100 #undef COAP_MAX_BLOCK_SZX #define COAP_MAX_BLOCK_SZX 2 diff --git a/examples/client.c b/examples/client.c index 2adc2e45..de4bac0b 100644 --- a/examples/client.c +++ b/examples/client.c @@ -141,6 +141,7 @@ order_opts(void *a, void *b) { static coap_pdu_t * coap_new_request(coap_context_t *ctx, + coap_session_t *session, method_t m, coap_list_t **options, unsigned char *data, @@ -148,7 +149,7 @@ coap_new_request(coap_context_t *ctx, coap_pdu_t *pdu; coap_list_t *opt; - if ( ! ( pdu = coap_new_pdu() ) ) + if ( ! ( pdu = coap_new_pdu(session) ) ) return NULL; pdu->hdr->type = msgtype; @@ -196,7 +197,7 @@ clear_obs(coap_context_t *ctx, coap_session_t *session) { pdu = coap_pdu_init(msgtype, COAP_REQUEST_GET, coap_new_message_id(ctx), - COAP_MAX_PDU_SIZE); + coap_session_max_pdu_size(session)); if (!pdu) { return tid; @@ -379,7 +380,7 @@ message_handler(struct coap_context_t *ctx, coap_opt_block_num(block_opt)); /* create pdu with request for next block */ - pdu = coap_new_request(ctx, method, NULL, NULL, 0); /* first, create bare PDU w/o any option */ + pdu = coap_new_request(ctx, session, method, NULL, NULL, 0); /* first, create bare PDU w/o any option */ if ( pdu ) { /* add URI components from optlist */ for (option = optlist; option; option = option->next ) { @@ -450,7 +451,7 @@ message_handler(struct coap_context_t *ctx, } /* create pdu with request for next block */ - pdu = coap_new_request(ctx, method, NULL, NULL, 0); /* first, create bare PDU w/o any option */ + pdu = coap_new_request(ctx, session, method, NULL, NULL, 0); /* first, create bare PDU w/o any option */ if (pdu) { /* add URI components from optlist */ @@ -1293,7 +1294,7 @@ main(int argc, char **argv) { if (flags & FLAGS_BLOCK) set_blocksize(); - if (! (pdu = coap_new_request(ctx, method, &optlist, payload.s, payload.length))) { + if (! (pdu = coap_new_request(ctx, session, method, &optlist, payload.s, payload.length))) { goto finish; } diff --git a/examples/contiki/coap-observer.c b/examples/contiki/coap-observer.c index 6e30d329..da892575 100644 --- a/examples/contiki/coap-observer.c +++ b/examples/contiki/coap-observer.c @@ -133,7 +133,7 @@ PROCESS_THREAD(coap_server_process, ev, data) request = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_GET, coap_new_message_id(coap_context), - COAP_MAX_PDU_SIZE); + COAP_DEFFAULT_PDU_SIZE); coap_split_uri((unsigned char *)resource, strlen(resource), &uri); diff --git a/include/coap/block.h b/include/coap/block.h index 9535e29b..b89a3623 100644 --- a/include/coap/block.h +++ b/include/coap/block.h @@ -22,9 +22,9 @@ #ifndef COAP_MAX_BLOCK_SZX /** * The largest value for the SZX component in a Block option. Note that - * 1 << (COAP_MAX_BLOCK_SZX + 4) should not exceed COAP_MAX_PDU_SIZE. + * 1 << (COAP_MAX_BLOCK_SZX + 4) should not exceed COAP_DEFAULT_PDU_SIZE. */ -#define COAP_MAX_BLOCK_SZX 4 +#define COAP_MAX_BLOCK_SZX 6 #endif /* COAP_MAX_BLOCK_SZX */ /** diff --git a/include/coap/coap_dtls.h b/include/coap/coap_dtls.h index bb9759ab..65858e86 100644 --- a/include/coap/coap_dtls.h +++ b/include/coap/coap_dtls.h @@ -20,13 +20,6 @@ * @{ */ -/** - * The maximum expected size of a DTLS record. This constant is used - * to allocate storage in the sendqueue for a DTLS session in case the - * data cannot be sent immediately. - */ -#define COAP_DTLS_MAX_PACKET_SIZE COAP_MAX_PDU_SIZE - /** Returns 1 if support for DTLS is enabled, or 0 otherwise. */ int coap_dtls_is_supported(void); @@ -44,10 +37,10 @@ int coap_dtls_get_log_level(void); * @return A DTLS context object or NULL on error; */ void * -coap_dtls_new_context( struct coap_context_t *coap_context ); +coap_dtls_new_context(struct coap_context_t *coap_context); /** Releases the storage allocated for @p dtls_context. */ -void coap_dtls_free_context( void *dtls_context ); +void coap_dtls_free_context(void *dtls_context); /** * Create a new client-side session. This should send a HELLO to the server. @@ -55,7 +48,7 @@ void coap_dtls_free_context( void *dtls_context ); * @param session The CoAP session * @return Opaque handle to underlying TLS library object containing security parameters for the session. */ -void *coap_dtls_new_client_session( coap_session_t *session ); +void *coap_dtls_new_client_session(coap_session_t *session); /** * Create a new server-side session. @@ -65,14 +58,14 @@ void *coap_dtls_new_client_session( coap_session_t *session ); * @param session The CoAP session * @return Opaque handle to underlying TLS library object containing security parameters for the session. */ -void *coap_dtls_new_server_session( coap_session_t *session ); +void *coap_dtls_new_server_session(coap_session_t *session); /** * Terminates the DTLS session (may send an ALERT if necessary) then frees the underlying TLS library object containing security parameters for the session. * * @param session The CoAP session */ -void coap_dtls_free_session( coap_session_t *session ); +void coap_dtls_free_session(coap_session_t *session); /** * Send data to a DTLS peer. @@ -81,9 +74,9 @@ void coap_dtls_free_session( coap_session_t *session ); * @param pdu The CoAP PDU * @return 0 if this would be blocking, -1 if there is an error or the number of cleartext bytes sent */ -int coap_dtls_send( coap_session_t *session, - const uint8_t *data, - size_t data_len ); +int coap_dtls_send(coap_session_t *session, + const uint8_t *data, + size_t data_len); /** * Do all pending retransmits and get next timeout @@ -91,7 +84,7 @@ int coap_dtls_send( coap_session_t *session, * @param dtls_context The DTLS context * @return <0 If not implemented, i.e. each session has its own timeout, 0 if no timeout, >0 Number of milliseconds until the next timeout. */ -int coap_dtls_get_context_timeout( void *dtls_context ); +int coap_dtls_get_context_timeout(void *dtls_context); /** * Get next timeout for this session. @@ -99,14 +92,14 @@ int coap_dtls_get_context_timeout( void *dtls_context ); * @param session The CoAP session * @return <0 If no event is pending, >=0 Number of milliseconds until the next timeout. */ -int coap_dtls_get_timeout( coap_session_t *session ); +int coap_dtls_get_timeout(coap_session_t *session); /** * Handle a DTLS timeout expiration. * * @param session The CoAP session */ -void coap_dtls_handle_timeout( coap_session_t *session ); +void coap_dtls_handle_timeout(coap_session_t *session); /** * Handling incoming data from a DTLS peer. @@ -116,9 +109,9 @@ void coap_dtls_handle_timeout( coap_session_t *session ); * @param data_len Encrypted datagram size * @return result of coap_handle_message on the decrypted CoAP PDU or -1 for error. */ -int coap_dtls_receive( coap_session_t *session, - const uint8_t *data, - size_t data_len); +int coap_dtls_receive(coap_session_t *session, + const uint8_t *data, + size_t data_len); /** * Handling client HELLO messages from a new candiate peer. @@ -129,9 +122,18 @@ int coap_dtls_receive( coap_session_t *session, * @param data_len Encrypted datagram size * @return 0 if a cookie verification message has been sent, 1 if the HELLO contains a valid cookie and a server session should be created, -1 if the message is invalid. */ -int coap_dtls_hello( coap_session_t *session, - const uint8_t *data, - size_t data_len ); +int coap_dtls_hello(coap_session_t *session, + const uint8_t *data, + size_t data_len); + +/** + * Get DTLS overhead over cleartext PDUs. + * + * @param session The CoAP session + * @return maximum number of bytes added by DTLS layer. + */ + +unsigned int coap_dtls_get_overhead(coap_session_t *session); /** @} */ diff --git a/include/coap/coap_io.h b/include/coap/coap_io.h index a4879aff..43da609a 100644 --- a/include/coap/coap_io.h +++ b/include/coap/coap_io.h @@ -15,6 +15,10 @@ #include "address.h" +#ifndef COAP_RXBUFFER_SIZE +#define COAP_RXBUFFER_SIZE 1472 +#endif /* COAP_RXBUFFER_SIZE */ + #ifdef _WIN32 typedef SOCKET coap_fd_t; #define coap_closesocket closesocket @@ -107,24 +111,17 @@ ssize_t coap_network_send( coap_socket_t *sock, const struct coap_session_t *ses * error, @p *packet is set to NULL. * * @param sock Socket to read data from - * @param packet A result parameter where a pointer to the received packet - * structure is stored. The caller must call coap_free_packet to - * release the storage used by this packet. + * @param packet Received packet metadata and payload. src and dst should be preset. * * @return The number of bytes received on success, or a value less than * zero on error. */ -ssize_t coap_network_read( coap_socket_t *sock, struct coap_packet_t **packet ); +ssize_t coap_network_read( coap_socket_t *sock, struct coap_packet_t *packet ); #ifndef coap_mcast_interface # define coap_mcast_interface(Local) 0 #endif -/** - * Releases the storage allocated for @p packet. - */ -void coap_free_packet(struct coap_packet_t *packet); - /** * Given a packet, set msg and msg_len to an address and length of the packet's * data in memory. @@ -164,7 +161,7 @@ struct coap_packet_t { coap_address_t dst; /**< the packet's destination address */ int ifindex; /**< the interface index */ size_t length; /**< length of payload */ - unsigned char payload[]; /**< payload */ + unsigned char payload[COAP_RXBUFFER_SIZE]; /**< payload */ }; #endif typedef struct coap_packet_t coap_packet_t; diff --git a/include/coap/coap_session.h b/include/coap/coap_session.h index b0237f0d..83df0f2f 100644 --- a/include/coap/coap_session.h +++ b/include/coap/coap_session.h @@ -55,9 +55,11 @@ typedef struct coap_session_t { coap_proto_t proto; /**< protocol used */ coap_session_type_t type; /**< client or server side socket */ coap_session_state_t state; /**< current state of relationaship with peer */ - int ref; /**< reference count from queues */ - coap_address_t local_addr; /**< local address and port */ + uint8_t ref; /**< reference count from queues */ + uint16_t mtu; /**< path mtu */ + uint16_t tls_overhead; /**< overhead of TLS layer */ coap_address_t remote_addr; /**< remote address and port */ + coap_address_t local_addr; /**< local address and port */ int ifindex; /**< interface index */ coap_socket_t sock; /**< socket object for the session, if any */ struct coap_endpoint_t *endpoint; /**< session's endpoint */ @@ -109,6 +111,23 @@ void coap_session_reset(coap_session_t *session); */ void coap_session_connected(coap_session_t *session); +/** +* Set the session MTU. This is the maximum message size that can be sent, +* excluding IP and UDP overhead. +* +* @param session The CoAP session. +* @param mtu maximum message size +*/ +void coap_session_set_mtu(coap_session_t *session, unsigned mtu); + +/** + * Get maximum acceptable PDU size + * + * @param session The CoAP session. + * @return maximum PDU size + */ +unsigned int coap_session_max_pdu_size(coap_session_t *session); + /** * Creates a new client session to the designated server. * @param ctx The CoAP context. @@ -179,8 +198,9 @@ coap_session_delay_pdu(coap_session_t *session, coap_pdu_t *pdu, int retransmit_ */ typedef struct coap_endpoint_t { struct coap_endpoint_t *next; - struct coap_context_t *context; /**< endpoint's context */ + struct coap_context_t *context; /**< endpoint's context */ coap_proto_t proto; /**< protocol used on this interface */ + uint16_t default_mtu; /**< default mtu for this interface */ coap_socket_t sock; /**< socket object for the interface, if any */ coap_address_t bind_addr; /**< local interface address */ coap_session_t *sessions; /**< list of active sessions */ @@ -197,8 +217,18 @@ typedef struct coap_endpoint_t { coap_endpoint_t *coap_new_endpoint(struct coap_context_t *context, const coap_address_t *listen_addr, coap_proto_t proto); +/** +* Set the endpoint's default MTU. This is the maximum message size that can be +* sent, excluding IP and UDP overhead. +* +* @param session The CoAP session. +* @param mtu maximum message size +*/ +void coap_endpoint_set_default_mtu(coap_endpoint_t *ep, unsigned mtu); + void coap_free_endpoint(coap_endpoint_t *ep); + /** * Get endpoint description. * diff --git a/include/coap/lwippools.h b/include/coap/lwippools.h index 0bfb3f52..0c460674 100644 --- a/include/coap/lwippools.h +++ b/include/coap/lwippools.h @@ -35,6 +35,10 @@ #define MEMP_NUM_COAPPDU MEMP_NUM_COAPNODE #endif +#ifndef MEMP_NUM_COAPSESSION +#define MEMP_NUM_COAPSESSION 2 +#endif + #ifndef MEMP_NUM_COAP_SUBSCRIPTION #define MEMP_NUM_COAP_SUBSCRIPTION 4 #endif @@ -52,6 +56,7 @@ LWIP_MEMPOOL(COAP_ENDPOINT, MEMP_NUM_COAPENDPOINT, sizeof(coap_endpoint_t), "COA LWIP_MEMPOOL(COAP_PACKET, MEMP_NUM_COAPPACKET, sizeof(coap_packet_t), "COAP_PACKET") LWIP_MEMPOOL(COAP_NODE, MEMP_NUM_COAPNODE, sizeof(coap_queue_t), "COAP_NODE") LWIP_MEMPOOL(COAP_PDU, MEMP_NUM_COAPPDU, sizeof(coap_pdu_t), "COAP_PDU") +LWIP_MEMPOOL(COAP_SESSION, MEMP_NUM_COAPSESSION, sizeof(coap_session_t), "COAP_SESSION") LWIP_MEMPOOL(COAP_subscription, MEMP_NUM_COAP_SUBSCRIPTION, sizeof(coap_subscription_t), "COAP_subscription") LWIP_MEMPOOL(COAP_RESOURCE, MEMP_NUM_COAPRESOURCE, sizeof(coap_resource_t), "COAP_RESOURCE") LWIP_MEMPOOL(COAP_RESOURCEATTR, MEMP_NUM_COAPRESOURCEATTR, sizeof(coap_attr_t), "COAP_RESOURCEATTR") diff --git a/include/coap/mem.h b/include/coap/mem.h index fe333aaf..64a3efbe 100644 --- a/include/coap/mem.h +++ b/include/coap/mem.h @@ -38,7 +38,7 @@ typedef enum { COAP_PDU_BUF, COAP_RESOURCE, COAP_RESOURCEATTR, - COAP_DTLS_SESSION + COAP_SESSION } coap_memory_tag_t; #ifndef WITH_LWIP diff --git a/include/coap/net.h b/include/coap/net.h index a512b8e2..c16ccc0a 100644 --- a/include/coap/net.h +++ b/include/coap/net.h @@ -129,7 +129,7 @@ typedef struct coap_context_t { ssize_t (*network_send)(coap_socket_t *sock, const coap_session_t *session, const uint8_t *data, size_t datalen); - ssize_t (*network_read)(coap_socket_t *sock, struct coap_packet_t **packet); + ssize_t (*network_read)(coap_socket_t *sock, struct coap_packet_t *packet); size_t(*get_client_psk)(const coap_session_t *session, const uint8_t *hint, size_t hint_len, uint8_t *identity, size_t *identity_len, size_t max_identity_len, uint8_t *psk, size_t max_psk_len); size_t(*get_server_psk)(const coap_session_t *session, const uint8_t *identity, size_t identity_len, uint8_t *psk, size_t max_psk_len); @@ -527,11 +527,13 @@ int coap_option_check_critical(coap_context_t *ctx, * must be either sent with coap_sent() or released by coap_delete_pdu(). * * @param context The current coap context to use. + * @param session The CoAP session. * @param request The request for @c .well-known/core . * * @return A new 2.05 response for @c .well-known/core or NULL on error. */ coap_pdu_t *coap_wellknown_response(coap_context_t *context, + coap_session_t *session, coap_pdu_t *request); #endif /* _COAP_NET_H_ */ diff --git a/include/coap/option.h b/include/coap/option.h index a87b0529..5bb0e183 100644 --- a/include/coap/option.h +++ b/include/coap/option.h @@ -371,7 +371,7 @@ unsigned short coap_opt_delta(const coap_opt_t *opt); /** @deprecated { Use coap_opt_encode() instead. } */ #define COAP_OPT_SETDELTA(opt,val) \ - coap_opt_encode((opt), COAP_MAX_PDU_SIZE, (val), NULL, 0) + coap_opt_encode((opt), COAP_DEFAULT_PDU_SIZE, (val), NULL, 0) /** * Returns the length of the given option. @p opt must point to an option jump diff --git a/include/coap/pdu.h b/include/coap/pdu.h index 697e6e65..36293755 100644 --- a/include/coap/pdu.h +++ b/include/coap/pdu.h @@ -24,9 +24,9 @@ #define COAP_DEFAULT_PORT 5683 /* CoAP default UDP port */ #define COAPS_DEFAULT_PORT 5684 /* CoAP default UDP port for secure transmission */ #define COAP_DEFAULT_MAX_AGE 60 /* default maximum object lifetime in seconds */ -#ifndef COAP_MAX_PDU_SIZE -#define COAP_MAX_PDU_SIZE 1400 /* maximum size of a CoAP PDU */ -#endif /* COAP_MAX_PDU_SIZE */ +#ifndef COAP_DEFAULT_PDU_SIZE +#define COAP_DEFAULT_PDU_SIZE 1152 /* default maximum size of a CoAP PDU */ +#endif /* COAP_DEFAULT_PDU_SIZE */ #define COAP_DEFAULT_VERSION 1 /* version of CoAP supported */ #define COAP_DEFAULT_SCHEME "coap" /* the default scheme for CoAP URIs */ @@ -320,14 +320,11 @@ void coap_pdu_clear(coap_pdu_t *pdu, size_t size); /** * Creates a new CoAP PDU. - * The object is created on the heap and must be released using - * coap_delete_pdu() unless coap_send() is called in which case - * coap_send() will take care of calling coap_delete_pdu(). * * @deprecated This function allocates the maximum storage for each * PDU. Use coap_pdu_init() instead. */ -coap_pdu_t *coap_new_pdu(void); +coap_pdu_t *coap_new_pdu(struct coap_session_t *session); /** * Dispose of an CoAP PDU and frees associated storage. diff --git a/libcoap-1.map b/libcoap-1.map index 7b9c2517..af23fcd7 100644 --- a/libcoap-1.map +++ b/libcoap-1.map @@ -43,7 +43,6 @@ global: coap_free_async; coap_free_context; coap_free_endpoint; - coap_free_packet; coap_free_type; coap_get_block; coap_get_data; @@ -108,6 +107,7 @@ global: coap_send_ack; coap_send_error; coap_send_message_type; + coap_session_max_pdu_size; coap_session_release; coap_set_event_handler; coap_set_log_level; diff --git a/libcoap-1.sym b/libcoap-1.sym index d0f6dccd..3203e165 100644 --- a/libcoap-1.sym +++ b/libcoap-1.sym @@ -41,7 +41,6 @@ coap_flsll coap_free_async coap_free_context coap_free_endpoint -coap_free_packet coap_free_type coap_get_block coap_get_data @@ -107,6 +106,7 @@ coap_send_ack coap_send_error coap_send_message_type coap_session_release +coap_session_max_pdu_size coap_set_event_handler coap_set_log_level coap_show_pdu diff --git a/src/block.c b/src/block.c index 69fe9e9c..d8e25e75 100644 --- a/src/block.c +++ b/src/block.c @@ -16,7 +16,7 @@ #include "debug.h" #include "block.h" -#if (COAP_MAX_PDU_SIZE - 6) < (1 << (COAP_MAX_BLOCK_SZX + 4)) +#if (COAP_DEFAULT_PDU_SIZE - 6) < (1 << (COAP_MAX_BLOCK_SZX + 4)) #error "COAP_MAX_BLOCK_SZX too large" #endif diff --git a/src/coap_io.c b/src/coap_io.c index ab8e775d..8fc65fe1 100644 --- a/src/coap_io.c +++ b/src/coap_io.c @@ -130,12 +130,12 @@ void coap_socket_close(coap_socket_t *sock) { struct coap_endpoint_t * coap_malloc_endpoint(void) { - return (struct coap_endpoint_t *)coap_malloc(sizeof(struct coap_endpoint_t)); + return (struct coap_endpoint_t *)coap_malloc_type(COAP_ENDPOINT, sizeof(struct coap_endpoint_t)); } void coap_mfree_endpoint(struct coap_endpoint_t *ep) { - coap_free(ep); + coap_free_type(COAP_ENDPOINT, ep); } int @@ -459,24 +459,6 @@ coap_network_send(coap_socket_t *sock, const coap_session_t *session, const uint #define SIN6(A) ((struct sockaddr_in6 *)(A)) -#if !defined(WITH_CONTIKI) && !defined(WITH_LWIP) -static coap_packet_t * -coap_malloc_packet(void) { - coap_packet_t *packet; - const size_t need = sizeof(coap_packet_t) + COAP_MAX_PDU_SIZE; - - packet = (coap_packet_t *)coap_malloc(need); - if (packet) { - memset(packet, 0, need); - } - return packet; -} - -void -coap_free_packet(coap_packet_t *packet) { - coap_free(packet); -} -#endif /* !defined(WITH_CONTIKI) && !defined(WITH_LWIP) */ #ifdef WITH_CONTIKI COAP_STATIC_INLINE coap_packet_t * coap_malloc_packet(void) { @@ -489,12 +471,6 @@ coap_free_packet(coap_packet_t *packet) { } #endif /* WITH_CONTIKI */ -COAP_STATIC_INLINE size_t -coap_get_max_packetlength(const coap_packet_t *packet) { - (void)packet; - return COAP_MAX_PDU_SIZE; -} - void coap_packet_get_memmapped(coap_packet_t *packet, unsigned char **address, size_t *length) { *address = packet->payload; @@ -507,7 +483,7 @@ void coap_packet_set_addr(coap_packet_t *packet, const coap_address_t *src, cons } ssize_t -coap_network_read(coap_socket_t *sock, coap_packet_t **packet) { +coap_network_read(coap_socket_t *sock, coap_packet_t *packet) { ssize_t len = -1; assert(sock); @@ -520,19 +496,9 @@ coap_network_read(coap_socket_t *sock, coap_packet_t **packet) { sock->flags &= ~COAP_SOCKET_HAS_DATA; } - *packet = coap_malloc_packet(); - - if (!*packet) { - warn("coap_network_read: insufficient memory, drop packet\n"); - return -1; - } - - coap_address_init(&(*packet)->dst); /* the local interface address */ - coap_address_init(&(*packet)->src); /* the remote peer */ - if (sock->flags & COAP_SOCKET_CONNECTED) { #ifdef _WIN32 - len = recv(sock->fd, (char *)(*packet)->payload, (int)coap_get_max_packetlength(*packet), 0); + len = recv(sock->fd, (char *)packet->payload, COAP_RXBUFFER_SIZE, 0); #else len = recv(sock->fd, (*packet)->payload, coap_get_max_packetlength(*packet), 0); #endif @@ -544,14 +510,12 @@ coap_network_read(coap_socket_t *sock, coap_packet_t **packet) { #endif /* client-side ICMP destination unreachable, ignore it */ coap_log(LOG_WARNING, "coap_network_read: unreachable\n"); - coap_free_packet(*packet); - *packet = NULL; return -2; } coap_log(LOG_WARNING, "coap_network_read: %s\n", coap_socket_strerror()); goto error; } else if (len > 0) { - (*packet)->length = (size_t)len; + packet->length = (size_t)len; } } else { #if defined(_WIN32) @@ -564,13 +528,13 @@ coap_network_read(coap_socket_t *sock, coap_packet_t **packet) { struct msghdr mhdr; struct iovec iov[1]; - iov[0].iov_base = (*packet)->payload; - iov[0].iov_len = (iov_len_t)coap_get_max_packetlength(*packet); + iov[0].iov_base = packet->payload; + iov[0].iov_len = (iov_len_t)COAP_RXBUFFER_SIZE; memset(&mhdr, 0, sizeof(struct msghdr)); - mhdr.msg_name = (struct sockaddr*)&(*packet)->src.addr.st; - mhdr.msg_namelen = sizeof((*packet)->src.addr.st); + mhdr.msg_name = (struct sockaddr*)&packet->src.addr.st; + mhdr.msg_namelen = sizeof(packet->src.addr.st); mhdr.msg_iov = iov; mhdr.msg_iovlen = 1; @@ -601,8 +565,6 @@ coap_network_read(coap_socket_t *sock, coap_packet_t **packet) { if (errno == ECONNREFUSED) { #endif /* server-side ICMP destination unreachable, ignore it. The destination address is in msg_name. */ - coap_free_packet(*packet); - *packet = NULL; return 0; } coap_log(LOG_WARNING, "coap_network_read: %s\n", coap_socket_strerror()); @@ -610,16 +572,8 @@ coap_network_read(coap_socket_t *sock, coap_packet_t **packet) { } else { struct cmsghdr *cmsg; - (*packet)->src.size = mhdr.msg_namelen; - - /* use getsockname() to get the local port */ - (*packet)->dst.size = sizeof((*packet)->dst.addr); - if (getsockname(sock->fd, &(*packet)->dst.addr.sa, &(*packet)->dst.size) == COAP_SOCKET_ERROR) { - coap_log(LOG_DEBUG, "cannot determine local port\n"); - goto error; - } - - (*packet)->length = (size_t)len; + packet->src.size = mhdr.msg_namelen; + packet->length = (size_t)len; /* Walk through ancillary data records until the local interface * is found where the data was received. */ @@ -632,8 +586,8 @@ coap_network_read(coap_socket_t *sock, coap_packet_t **packet) { struct in6_pktinfo *p; } u; u.c = CMSG_DATA(cmsg); - (*packet)->ifindex = (int)(u.p->ipi6_ifindex); - memcpy(&(*packet)->dst.addr.sin6.sin6_addr, &u.p->ipi6_addr, sizeof(struct in6_addr)); + packet->ifindex = (int)(u.p->ipi6_ifindex); + memcpy(&packet->dst.addr.sin6.sin6_addr, &u.p->ipi6_addr, sizeof(struct in6_addr)); break; } @@ -645,21 +599,21 @@ coap_network_read(coap_socket_t *sock, coap_packet_t **packet) { struct in_pktinfo *p; } u; u.c = CMSG_DATA(cmsg); - (*packet)->ifindex = u.p->ipi_ifindex; - if ((*packet)->dst.addr.sa.sa_family == AF_INET6) { - memset((*packet)->dst.addr.sin6.sin6_addr.s6_addr, 0, 10); - (*packet)->dst.addr.sin6.sin6_addr.s6_addr[10] = 0xff; - (*packet)->dst.addr.sin6.sin6_addr.s6_addr[11] = 0xff; - memcpy((*packet)->dst.addr.sin6.sin6_addr.s6_addr + 12, &u.p->ipi_addr, sizeof(struct in_addr)); + packet->ifindex = u.p->ipi_ifindex; + if (packet->dst.addr.sa.sa_family == AF_INET6) { + memset(packet->dst.addr.sin6.sin6_addr.s6_addr, 0, 10); + packet->dst.addr.sin6.sin6_addr.s6_addr[10] = 0xff; + packet->dst.addr.sin6.sin6_addr.s6_addr[11] = 0xff; + memcpy(packet->dst.addr.sin6.sin6_addr.s6_addr + 12, &u.p->ipi_addr, sizeof(struct in_addr)); } else { - memcpy(&(*packet)->dst.addr.sin.sin_addr, &u.p->ipi_addr, sizeof(struct in_addr)); + memcpy(&packet->dst.addr.sin.sin_addr, &u.p->ipi_addr, sizeof(struct in_addr)); } break; } #elif defined(IP_RECVDSTADDR) if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) { - (*packet)->ifindex = 0; - memcpy(&(*packet)->dst.addr.sin.sin_addr, CMSG_DATA(cmsg), sizeof(struct in_addr)); + packet->ifindex = 0; + memcpy(&packet->dst.addr.sin.sin_addr, CMSG_DATA(cmsg), sizeof(struct in_addr)); break; } #endif /* IP_PKTINFO */ @@ -714,10 +668,8 @@ coap_network_read(coap_socket_t *sock, coap_packet_t **packet) { if (len >= 0) return len; #if !defined(WITH_LWIP) - error: - coap_free_packet(*packet); - *packet = NULL; - return -1; +error: + return -1; #endif } diff --git a/src/coap_io_lwip.c b/src/coap_io_lwip.c index 9942e633..636a4145 100644 --- a/src/coap_io_lwip.c +++ b/src/coap_io_lwip.c @@ -80,6 +80,8 @@ coap_endpoint_t *coap_new_endpoint(const coap_address_t *addr, int flags) { goto error; } + result->default_mtu = COAP_DEFAULT_PDU_SIZE; + return result; error: diff --git a/src/coap_notls.c b/src/coap_notls.c index 0b920cc7..a85c4489 100644 --- a/src/coap_notls.c +++ b/src/coap_notls.c @@ -96,6 +96,10 @@ coap_dtls_hello( coap_session_t *session UNUSED, return 0; } +unsigned int coap_dtls_get_overhead(coap_session_t *session) { + return 0; +} + #undef UNUSED #else /* !HAVE_LIBTINYDTLS && !HAVE_OPENSSL */ diff --git a/src/coap_openssl.c b/src/coap_openssl.c index e0d561ca..34052a59 100644 --- a/src/coap_openssl.c +++ b/src/coap_openssl.c @@ -323,7 +323,7 @@ void *coap_dtls_new_context(struct coap_context_t *coap_context) { BIO *bio; uint8_t cookie_secret[32]; memset(context, 0, sizeof(coap_dtls_context_t)); - context->ctx = SSL_CTX_new(DTLS_method()); + context->ctx = SSL_CTX_new(DTLSv1_2_method()); if (!context->ctx) goto error; SSL_CTX_set_min_proto_version(context->ctx, DTLS1_2_VERSION); @@ -583,13 +583,13 @@ int coap_dtls_receive(coap_session_t *session, assert(ssl != NULL); int in_init = SSL_in_init(ssl); - uint8_t pdu[COAP_MAX_PDU_SIZE]; + uint8_t pdu[COAP_RXBUFFER_SIZE]; ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl)); ssl_data->pdu = data; ssl_data->pdu_len = (unsigned)data_len; dtls_event = -1; - r = SSL_read(ssl, pdu, COAP_MAX_PDU_SIZE); + r = SSL_read(ssl, pdu, (int)sizeof(pdu)); if (r > 0) { return coap_handle_message(session->context, session, pdu, (size_t)r); } else { @@ -619,6 +619,60 @@ int coap_dtls_receive(coap_session_t *session, return r; } +unsigned int coap_dtls_get_overhead(coap_session_t *session) { + unsigned int overhead = 37; + const SSL_CIPHER *s_ciph = NULL; + if (session->tls != NULL) + s_ciph = SSL_get_current_cipher(session->tls); + if ( s_ciph ) { + unsigned int ivlen, maclen, blocksize = 1, pad = 0; + + const EVP_CIPHER *e_ciph; + const EVP_MD *e_md; + char cipher[128]; + + e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph)); + + switch (EVP_CIPHER_mode(e_ciph)) { + case EVP_CIPH_GCM_MODE: + ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; + maclen = EVP_GCM_TLS_TAG_LEN; + break; + + case EVP_CIPH_CCM_MODE: + ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN; + SSL_CIPHER_description(s_ciph, cipher, sizeof(cipher)); + if (strstr(cipher, "CCM8")) + maclen = 8; + else + maclen = 16; + break; + + case EVP_CIPH_CBC_MODE: + e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph)); + blocksize = EVP_CIPHER_block_size(e_ciph); + ivlen = EVP_CIPHER_iv_length(e_ciph); + pad = 1; + maclen = EVP_MD_size(e_md); + break; + + case EVP_CIPH_STREAM_CIPHER: + /* Seen with PSK-CHACHA20-POLY1305 */ + ivlen = 8; + maclen = 8; + break; + + default: + SSL_CIPHER_description(s_ciph, cipher, sizeof(cipher)); + coap_log(LOG_WARNING, "Unknown overhead for DTLS with cipher %s\n", cipher); + ivlen = 8; + maclen = 16; + break; + } + overhead = DTLS1_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 + pad; + } + return overhead; +} #else /* !HAVE_OPENSSL */ /* make compilers happy that do not like empty modules */ diff --git a/src/coap_session.c b/src/coap_session.c index 91a706f8..c6277bec 100644 --- a/src/coap_session.c +++ b/src/coap_session.c @@ -40,7 +40,7 @@ coap_session_release(coap_session_t *session) { static coap_session_t * coap_make_session(coap_proto_t proto, coap_session_type_t type, const coap_address_t *local, const coap_address_t *remote, int ifindex, coap_context_t *context, coap_endpoint_t *endpoint) { - coap_session_t *session = (coap_session_t*)coap_malloc(sizeof(coap_session_t)); + coap_session_t *session = (coap_session_t*)coap_malloc_type(COAP_SESSION, sizeof(coap_session_t)); if (!session) return NULL; memset(session, 0, sizeof(*session)); @@ -57,6 +57,17 @@ coap_make_session(coap_proto_t proto, coap_session_type_t type, const coap_addre session->ifindex = ifindex; session->context = context; session->endpoint = endpoint; + if (endpoint) + session->mtu = endpoint->default_mtu; + else + session->mtu = COAP_DEFAULT_PDU_SIZE; + if (proto == COAP_PROTO_DTLS) { + session->tls_overhead = 29; + if (session->tls_overhead >= session->mtu) { + session->tls_overhead = session->mtu; + coap_log(LOG_ERR, "DTLS overhead exceeds MTU\n"); + } + } return session; } @@ -92,7 +103,19 @@ void coap_session_free(coap_session_t *session) { debug("*** %s: session closed\n", coap_session_str(session)); - coap_free(session); + coap_free_type(COAP_SESSION, session); +} + +unsigned int coap_session_max_pdu_size(coap_session_t *session) { + return session->mtu - session->tls_overhead; +} + +void coap_session_set_mtu(coap_session_t *session, unsigned mtu) { + session->mtu = (uint16_t)mtu; + if (session->tls_overhead >= session->mtu) { + session->tls_overhead = session->mtu; + coap_log(LOG_ERR, "DTLS overhead exceeds MTU\n"); + } } ssize_t coap_session_send(coap_session_t *session, const uint8_t *data, size_t datalen) { @@ -129,7 +152,17 @@ coap_session_delay_pdu(coap_session_t *session, coap_pdu_t *pdu, int retransmit_ void coap_session_connected(coap_session_t *session) { debug("*** %s: session connected\n", coap_session_str(session)); + session->state = COAP_SESSION_STATE_ESTABLISHED; + + if ( session->proto==COAP_PROTO_DTLS) { + session->tls_overhead = (uint16_t)coap_dtls_get_overhead(session); + if (session->tls_overhead >= session->mtu) { + session->tls_overhead = session->mtu; + coap_log(LOG_ERR, "DTLS overhead exceeds MTU\n"); + } + } + while (session->sendqueue && session->state == COAP_SESSION_STATE_ESTABLISHED) { ssize_t bytes_written; coap_pdu_queue_t *q = session->sendqueue; @@ -417,6 +450,8 @@ coap_new_endpoint(coap_context_t *context, const coap_address_t *listen_addr, co ep->hello.endpoint = ep; } + ep->default_mtu = COAP_DEFAULT_PDU_SIZE; + LL_PREPEND(context->endpoint, ep); return ep; @@ -425,6 +460,10 @@ error: return NULL; } +void coap_endpoint_set_default_mtu(coap_endpoint_t *ep, unsigned mtu) { + ep->default_mtu = (uint16_t)mtu; +} + void coap_free_endpoint(coap_endpoint_t *ep) { if (ep) { diff --git a/src/coap_tinydtls.c b/src/coap_tinydtls.c index 8b2023fc..64d6673f 100644 --- a/src/coap_tinydtls.c +++ b/src/coap_tinydtls.c @@ -356,6 +356,10 @@ coap_dtls_hello(coap_session_t *session, return res; } +unsigned int coap_dtls_get_overhead(coap_session_t *session) { + return 13 + 8 + 8; +} + #else /* !HAVE_LIBTINYDTLS */ /* make compilers happy that do not like empty modules */ diff --git a/src/debug.c b/src/debug.c index 8e714dcd..da4dca04 100644 --- a/src/debug.c +++ b/src/debug.c @@ -377,7 +377,7 @@ is_binary(int content_format) { void coap_show_pdu(const coap_pdu_t *pdu) { - unsigned char buf[COAP_MAX_PDU_SIZE]; /* need some space for output creation */ + unsigned char buf[COAP_DEFAULT_PDU_SIZE]; /* need some space for output creation */ size_t buf_len = 0; /* takes the number of bytes written to buf */ int encode = 0, have_options = 0, i; coap_opt_iterator_t opt_iter; diff --git a/src/mem.c b/src/mem.c index a06c4ddb..a3880659 100644 --- a/src/mem.c +++ b/src/mem.c @@ -59,8 +59,9 @@ struct coap_string_t { #include "pdu.h" #include "coap_io.h" #include "resource.h" +#include "coap_session.h" -#define COAP_MAX_PACKET_SIZE (sizeof(coap_packet_t) + COAP_MAX_PDU_SIZE) +#define COAP_MAX_PACKET_SIZE (sizeof(coap_packet_t) + COAP_RXBUFFER_SIZE) #define COAP_MAX_PACKETS 2 typedef union { @@ -70,6 +71,7 @@ typedef union { MEMB(string_storage, struct coap_string_t, COAP_MAX_STRINGS); MEMB(packet_storage, coap_packetbuf_t, COAP_MAX_PACKETS); +MEMB(session_storage, coap_session_t, COAP_MAX_SESSIONS); MEMB(node_storage, coap_queue_t, COAP_PDU_MAXCNT); MEMB(pdu_storage, coap_pdu_t, COAP_PDU_MAXCNT); MEMB(pdu_buf_storage, coap_packetbuf_t, COAP_PDU_MAXCNT); @@ -81,6 +83,7 @@ get_container(coap_memory_tag_t type) { switch(type) { case COAP_PACKET: return &packet_storage; case COAP_NODE: return &node_storage; + case COAP_SESSION: return &session_storage; case COAP_PDU: return &pdu_storage; case COAP_PDU_BUF: return &pdu_buf_storage; case COAP_RESOURCE: return &resource_storage; @@ -95,6 +98,7 @@ coap_memory_init(void) { memb_init(&string_storage); memb_init(&packet_storage); memb_init(&node_storage); + memb_init(&session_storage); memb_init(&pdu_storage); memb_init(&pdu_buf_storage); memb_init(&resource_storage); diff --git a/src/net.c b/src/net.c index b0cde5e1..1b3bbb98 100644 --- a/src/net.c +++ b/src/net.c @@ -942,12 +942,21 @@ coap_handle_message_for_proto(coap_context_t *ctx, coap_session_t *session, coap static int coap_read_session(coap_context_t *ctx, coap_session_t *session, coap_tick_t now) { ssize_t bytes_read = -1; - coap_packet_t *packet = NULL; int result = -1; /* the value to be returned */ +#ifdef WITH_CONTIKI + coap_packet_t *packet = coap_malloc_packet(); +#else /* WITH_CONTIKI */ + coap_packet_t s_packet; + coap_packet_t *packet = &s_packet; +#endif /* WITH_CONTIKI */ assert(session->sock.flags & COAP_SOCKET_CONNECTED); - bytes_read = ctx->network_read(&session->sock, &packet); + if (packet) { + coap_address_copy(&packet->src, &session->remote_addr); + coap_address_copy(&packet->dst, &session->local_addr); + bytes_read = ctx->network_read(&session->sock, packet); + } if (bytes_read < 0) { if (bytes_read == -2) @@ -961,8 +970,10 @@ coap_read_session(coap_context_t *ctx, coap_session_t *session, coap_tick_t now) result = coap_handle_message_for_proto(ctx, session, packet); } +#ifdef WITH_CONTIKI if ( packet ) coap_free_packet(packet); +#endif return result; } @@ -970,10 +981,21 @@ coap_read_session(coap_context_t *ctx, coap_session_t *session, coap_tick_t now) static int coap_read_endpoint(coap_context_t *ctx, coap_endpoint_t *endpoint, coap_tick_t now) { ssize_t bytes_read = -1; - coap_packet_t *packet = NULL; int result = -1; /* the value to be returned */ +#ifdef WITH_CONTIKI + coap_packet_t *packet = coap_malloc_packet(); +#else /* WITH_CONTIKI */ + coap_packet_t s_packet; + coap_packet_t *packet = &s_packet; +#endif /* WITH_CONTIKI */ - bytes_read = ctx->network_read(&endpoint->sock, &packet); + assert(endpoint->sock.flags&COAP_SOCKET_BOUND); + + if (packet) { + coap_address_init(&packet->src); + coap_address_copy(&packet->dst, &endpoint->bind_addr); + bytes_read = ctx->network_read(&endpoint->sock, packet); + } if (bytes_read < 0) { warn("* %s: read failed\n", coap_endpoint_str(endpoint)); @@ -987,8 +1009,10 @@ coap_read_endpoint(coap_context_t *ctx, coap_endpoint_t *endpoint, coap_tick_t n } } - if ( packet ) +#ifdef WITH_CONTIKI + if (packet) coap_free_packet(packet); +#endif return result; } @@ -1332,7 +1356,8 @@ get_wkc_len(coap_context_t *context, coap_opt_t *query_filter) { #define SZX_TO_BYTES(SZX) ((size_t)(1 << ((SZX) + 4))) coap_pdu_t * -coap_wellknown_response(coap_context_t *context, coap_pdu_t *request) { +coap_wellknown_response(coap_context_t *context, coap_session_t *session, + coap_pdu_t *request) { coap_pdu_t *resp; coap_opt_iterator_t opt_iter; size_t len, wkc_len; @@ -1347,7 +1372,7 @@ coap_wellknown_response(coap_context_t *context, coap_pdu_t *request) { ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON, COAP_RESPONSE_CODE(205), - request->hdr->id, COAP_MAX_PDU_SIZE); + request->hdr->id, coap_session_max_pdu_size(session)); if (!resp) { debug("coap_wellknown_response: cannot create PDU\n"); return NULL; @@ -1592,7 +1617,7 @@ handle_request(coap_context_t *context, coap_queue_t *node) { if (is_wkc(key)) { /* request for .well-known/core */ if (node->pdu->hdr->code == COAP_REQUEST_GET) { /* GET */ info("create default response for %s\n", COAP_DEFAULT_URI_WELLKNOWN); - response = coap_wellknown_response(context, node->pdu); + response = coap_wellknown_response(context, node->session, node->pdu); } else { debug("method not allowed for .well-known/core\n"); response = coap_new_error_response(node->pdu, COAP_RESPONSE_CODE(405), @@ -1630,7 +1655,7 @@ handle_request(coap_context_t *context, coap_queue_t *node) { response = coap_pdu_init(node->pdu->hdr->type == COAP_MESSAGE_CON ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON, - 0, node->pdu->hdr->id, COAP_MAX_PDU_SIZE); + 0, node->pdu->hdr->id, coap_session_max_pdu_size(node->session)); /* Implementation detail: coap_add_token() immediately returns 0 if response == NULL */ @@ -1705,7 +1730,7 @@ handle_request(coap_context_t *context, coap_queue_t *node) { } else { if (WANT_WKC(node->pdu, key)) { debug("create default response for %s\n", COAP_DEFAULT_URI_WELLKNOWN); - response = coap_wellknown_response(context, node->pdu); + response = coap_wellknown_response(context, node->session, node->pdu); debug("have wellknown response %p\n", (void *)response); } else response = coap_new_error_response(node->pdu, COAP_RESPONSE_CODE(405), diff --git a/src/pdu.c b/src/pdu.c index 206768ab..fa37c784 100644 --- a/src/pdu.c +++ b/src/pdu.c @@ -32,6 +32,7 @@ #include "option.h" #include "encode.h" #include "mem.h" +#include "coap_session.h" void coap_pdu_clear(coap_pdu_t *pdu, size_t size) { @@ -84,13 +85,20 @@ coap_pdu_init(unsigned char type, unsigned char code, unsigned short id, size_t size) { coap_pdu_t *pdu; #ifdef WITH_LWIP - struct pbuf *p; + struct pbuf *p; #endif - assert(size <= COAP_MAX_PDU_SIZE); +#ifdef WITH_CONTIKI + assert(size <= COAP_RXBUFFER_SIZE); /* Size must be large enough to fit the header. */ - if (size < sizeof(coap_hdr_t) || size > COAP_MAX_PDU_SIZE) + if (size < sizeof(coap_hdr_t) || size > COAP_RXBUFFER_SIZE) return NULL; +#else + assert(size <= 16384); + /* Size must be large enough to fit the header. */ + if (size < sizeof(coap_hdr_t) || size > 16384) + return NULL; +#endif /* size must be large enough for hdr */ #if !defined(WITH_LWIP) @@ -123,13 +131,13 @@ coap_pdu_init(unsigned char type, unsigned char code, } coap_pdu_t * -coap_new_pdu(void) { +coap_new_pdu(struct coap_session_t *session) { coap_pdu_t *pdu; #ifndef WITH_CONTIKI - pdu = coap_pdu_init(0, 0, ntohs((uint16_t)COAP_INVALID_TID), COAP_MAX_PDU_SIZE); + pdu = coap_pdu_init(0, 0, ntohs((uint16_t)COAP_INVALID_TID), coap_session_max_pdu_size(session)); #else /* WITH_CONTIKI */ - pdu = coap_pdu_init(0, 0, uip_ntohs(COAP_INVALID_TID), COAP_MAX_PDU_SIZE); + pdu = coap_pdu_init(0, 0, uip_ntohs(COAP_INVALID_TID), coap_session_max_pdu_size(session)); #endif /* WITH_CONTIKI */ #ifndef NDEBUG diff --git a/src/resource.c b/src/resource.c index bac05d58..4afee298 100644 --- a/src/resource.c +++ b/src/resource.c @@ -660,7 +660,7 @@ coap_notify_observers(coap_context_t *context, coap_resource_t *r) { coap_tid_t tid = COAP_INVALID_TID; obs->dirty = 0; /* initialize response */ - response = coap_pdu_init(COAP_MESSAGE_CON, 0, 0, COAP_MAX_PDU_SIZE); + response = coap_pdu_init(COAP_MESSAGE_CON, 0, 0, coap_session_max_pdu_size(obs->session)); if (!response) { obs->dirty = 1; r->partiallydirty = 1; diff --git a/tests/test_error_response.c b/tests/test_error_response.c index 37afba47..348091a9 100644 --- a/tests/test_error_response.c +++ b/tests/test_error_response.c @@ -329,7 +329,7 @@ t_error_response8(void) { static int t_error_response_tests_create(void) { - pdu = coap_pdu_init(0, 0, 0, COAP_MAX_PDU_SIZE); + pdu = coap_pdu_init(0, 0, 0, COAP_DEFAULT_PDU_SIZE); return pdu == NULL; } diff --git a/tests/test_pdu.c b/tests/test_pdu.c index 13608308..40b9eec0 100644 --- a/tests/test_pdu.c +++ b/tests/test_pdu.c @@ -622,7 +622,7 @@ t_encode_pdu11(void) { static int t_pdu_tests_create(void) { - pdu = coap_pdu_init(0, 0, 0, COAP_MAX_PDU_SIZE); + pdu = coap_pdu_init(0, 0, 0, COAP_DEFAULT_PDU_SIZE); return pdu == NULL; } diff --git a/tests/test_wellknown.c b/tests/test_wellknown.c index f3d32214..dcbe4546 100644 --- a/tests/test_wellknown.c +++ b/tests/test_wellknown.c @@ -132,7 +132,7 @@ t_wellknown3(void) { coap_print_status_t result; int j; coap_resource_t *r; - static char uris[2 * COAP_MAX_PDU_SIZE]; + static char uris[2 * COAP_DEFAULT_PDU_SIZE]; unsigned char *uribuf = (unsigned char *)uris; unsigned char buf[40]; size_t buflen = sizeof(buf); @@ -264,7 +264,7 @@ t_wkc_tests_create(void) { /* add resources to coap context */ if (ctx && pdu) { coap_resource_t *r; - static char _buf[2 * COAP_MAX_PDU_SIZE]; + static char _buf[2 * COAP_DEFAULT_PDU_SIZE]; unsigned char *buf = (unsigned char *)_buf; int i;