Updated libcoap to send messages using secure port
authorSachin Agrawal <sachin.agrawal@intel.com>
Wed, 5 Nov 2014 02:30:34 +0000 (18:30 -0800)
committerSachin Agrawal <sachin.agrawal@intel.com>
Wed, 5 Nov 2014 21:46:17 +0000 (13:46 -0800)
Whenever a REST request is received by OIC Stack on secure
port, it needs to keep track of this fact for two reasons:
1) It allows upper layer to grant/deny access to secure resource
if the request was unauthenticated.
2) It also allows OC Stack to encrypt the response for a secure
request.
Since existing code was using a mechanism of send_flag to keep
track of various send mechanisms, it was modified to a bit mask
flag.

Change-Id: I293d4378a1e90234daf2553b6c6defdb6a3abac5
Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
csdk/libcoap-4.1.1/net.c
csdk/libcoap-4.1.1/net.h
csdk/occoap/include/occoaphelper.h
csdk/occoap/src/occoap.c
csdk/occoap/src/occoaphelper.c

index cda51d6..d95e1d6 100644 (file)
@@ -511,7 +511,7 @@ void coap_transaction_id(const coap_address_t *peer, const coap_pdu_t *pdu,
 }
 
 coap_tid_t coap_send_ack(coap_context_t *context, const coap_address_t *dst,
-        coap_pdu_t *request) {
+        coap_pdu_t *request, coap_send_flags_t flag) {
     coap_pdu_t *response;
     coap_tid_t result = COAP_INVALID_TID;
 
@@ -519,7 +519,7 @@ coap_tid_t coap_send_ack(coap_context_t *context, const coap_address_t *dst,
         response = coap_pdu_init(COAP_MESSAGE_ACK, 0, request->hdr->id,
                 sizeof(coap_pdu_t));
         if (response) {
-            result = coap_send(context, dst, response, SEND_NOW);
+            result = coap_send(context, dst, response, flag);
             coap_delete_pdu(response);
         }
     }
@@ -623,7 +623,8 @@ coap_send_impl(coap_context_t *context,
 #endif /* WITH_LWIP */
 
 coap_tid_t coap_send_error(coap_context_t *context, coap_pdu_t *request,
-        const coap_address_t *dst, unsigned char code, coap_opt_filter_t opts) {
+        const coap_address_t *dst, unsigned char code, coap_opt_filter_t opts,
+        coap_send_flags_t flag) {
     coap_pdu_t *response;
     coap_tid_t result = COAP_INVALID_TID;
 
@@ -632,7 +633,7 @@ coap_tid_t coap_send_error(coap_context_t *context, coap_pdu_t *request,
 
     response = coap_new_error_response(request, code, opts);
     if (response) {
-        result = coap_send(context, dst, response, SEND_NOW);
+        result = coap_send(context, dst, response, flag);
         coap_delete_pdu(response);
     }
 
@@ -640,14 +641,15 @@ coap_tid_t coap_send_error(coap_context_t *context, coap_pdu_t *request,
 }
 
 coap_tid_t coap_send_message_type(coap_context_t *context,
-        const coap_address_t *dst, coap_pdu_t *request, unsigned char type) {
+        const coap_address_t *dst, coap_pdu_t *request,
+        coap_send_flags_t flag, unsigned char type) {
     coap_pdu_t *response;
     coap_tid_t result = COAP_INVALID_TID;
 
     if (request) {
         response = coap_pdu_init(type, 0, request->hdr->id, sizeof(coap_pdu_t));
         if (response) {
-            result = coap_send(context, dst, response, SEND_NOW);
+            result = coap_send(context, dst, response, flag);
             coap_delete_pdu(response);
         }
     }
@@ -655,7 +657,7 @@ coap_tid_t coap_send_message_type(coap_context_t *context,
 }
 
 coap_tid_t coap_send(coap_context_t *context,
-        const coap_address_t *dst, coap_pdu_t *pdu, const uint8_t flag)
+        const coap_address_t *dst, coap_pdu_t *pdu, coap_send_flags_t flag)
 {
     coap_queue_t *node = NULL;
     coap_tick_t now;
@@ -665,10 +667,10 @@ coap_tid_t coap_send(coap_context_t *context,
 
     if (!context)
         return COAP_INVALID_TID;
-    if(flag != SEND_RETX){
+    if(!(flag & SEND_RETX)){
         coap_transaction_id(dst, pdu, &tid);
     }
-    if(flag == SEND_NOW || flag == SEND_RETX)
+    if((flag & SEND_NOW) || (flag & SEND_RETX))
     {
         goto sending;
     }
@@ -681,8 +683,7 @@ coap_tid_t coap_send(coap_context_t *context,
 
     prng((unsigned char * )&r, sizeof(r));
     /* add randomized RESPONSE_TIMEOUT to determine retransmission timeout */
-    if(flag == SEND_NOW_CON)
-    {
+    if(flag & SEND_NOW_CON) {
         node->timeout = COAP_DEFAULT_RESPONSE_TIMEOUT * COAP_TICKS_PER_SECOND
                 + (COAP_DEFAULT_RESPONSE_TIMEOUT >> 1)
                 * ((COAP_TICKS_PER_SECOND * (r & 0xFF)) >> 8);
@@ -693,6 +694,10 @@ coap_tid_t coap_send(coap_context_t *context,
         node->delayedResponse = 1;
     }
 
+    if (flag & SEND_SECURE_PORT) {
+        node->secure = 1;
+    }
+
     memcpy(&node->remote, dst, sizeof(coap_address_t));
     node->pdu = pdu;
     node->id = tid;
@@ -739,7 +744,7 @@ coap_tid_t coap_send(coap_context_t *context,
     }
     #endif /* WITH_CONTIKI */
 
-    if(flag == SEND_NOW_CON)
+    if(flag & SEND_NOW_CON)
     {
         goto sending;
     }
@@ -758,6 +763,7 @@ coap_tid_t coap_send(coap_context_t *context,
 
 coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node) {
     coap_tid_t tid = COAP_INVALID_TID;
+    coap_send_flags_t flag;
 
     if (!context || !node)
         return COAP_INVALID_TID;
@@ -773,8 +779,9 @@ coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node) {
 #endif
 
         debug("** retransmission #%d of transaction %d\n", node->retransmit_cnt,
-                ntohs(node->pdu->hdr->id));
-        tid = coap_send(context, (coap_address_t *)&(node->remote),node->pdu, SEND_RETX);
+            ntohs(node->pdu->hdr->id));
+        flag = (coap_send_flags_t)(SEND_RETX | (node->secure ? SEND_SECURE_PORT : 0));
+        tid = coap_send(context, (coap_address_t *)&(node->remote),node->pdu, flag);
         return (tid == COAP_INVALID_TID)? COAP_INVALID_TID : node->id;
     }
 
@@ -1241,8 +1248,10 @@ static void handle_request(coap_context_t *context, coap_queue_t *rcvd) {
     if (context->request_handler) {
         context->request_handler(context, rcvd);
     } else {
+        coap_send_flags_t flag = SEND_NOW;
+        flag = (coap_send_flags_t)(flag | (rcvd->secure ? SEND_SECURE_PORT : 0));
         /* send ACK if rcvd is confirmable (i.e. a separate response) */
-        coap_send_ack(context, &rcvd->remote, rcvd->pdu);
+        coap_send_ack(context, &rcvd->remote, rcvd->pdu, flag);
     }
 }
 
@@ -1252,8 +1261,10 @@ static void handle_response(coap_context_t *context, coap_queue_t *rcvd) {
     if (context->response_handler) {
         context->response_handler(context, rcvd);
     } else {
+        coap_send_flags_t flag = SEND_NOW;
+        flag = (coap_send_flags_t)(flag | (rcvd->secure ? SEND_SECURE_PORT : 0));
         /* send ACK if rcvd is confirmable (i.e. a separate response) */
-        coap_send_ack(context, &rcvd->remote, rcvd->pdu);
+        coap_send_ack(context, &rcvd->remote, rcvd->pdu, flag);
     }
 }
 
@@ -1327,8 +1338,10 @@ handle_locally(coap_context_t *context __attribute__ ((unused)),
                     if (!response)
                         warn("coap_dispatch: cannot create error reponse\n");
                     else {
-                        if (coap_send(context, &rcvd->remote,
-                                response, SEND_NOW) == COAP_INVALID_TID) {
+                        coap_send_flags_t flag = SEND_NOW;
+                        flag = (coap_send_flags_t)(flag | rcvd->secure ? SEND_SECURE_PORT : 0);
+                        if (coap_send(context, &rcvd->remote, response, flag)
+                                == COAP_INVALID_TID) {
                             warn("coap_dispatch: error sending reponse\n");
                         }
                         coap_delete_pdu(response);
@@ -1428,9 +1441,12 @@ handle_locally(coap_context_t *context __attribute__ ((unused)),
                     handle_response(context, rcvd);
                 }
                 else {
+                    coap_send_flags_t flag;
+                    flag = (coap_send_flags_t)(SEND_NOW |
+                            (rcvd->secure ? SEND_SECURE_PORT : 0));
                     debug("dropped message with invalid code\n");
                     coap_send_message_type(context, &rcvd->remote, rcvd->pdu,
-                            COAP_MESSAGE_RST);
+                            flag, COAP_MESSAGE_RST);
                 }
             }
 
index 51728f4..c9d803c 100644 (file)
@@ -50,10 +50,13 @@ extern "C" {
 #include "pdu.h"
 #include "coap_time.h"
 
-#define SEND_NOW        (1) /*Flag used when sending non-confirmable, ACK and RESET coap pdus*/
-#define SEND_NOW_CON    (2) /*Flag used when sending confirmable coap pdu*/
-#define SEND_DELAYED    (3) /*Flag used to delay the transmission of coap pdu*/
-#define SEND_RETX       (4) /*Flag used to retransmit a confirmable pdu*/
+typedef enum {
+    SEND_NOW            = (1 << 0), /*Flag used when sending non-confirmable, ACK and RESET coap pdus*/
+    SEND_NOW_CON        = (1 << 1), /*Flag used when sending confirmable coap pdu*/
+    SEND_DELAYED        = (1 << 2), /*Flag used to delay the transmission of coap pdu*/
+    SEND_RETX           = (1 << 3), /*Flag used to retransmit a confirmable pdu*/
+    SEND_SECURE_PORT    = (1 << 4) /*Flag used to indicate that PDU needs to be transmitted on secure port */
+} coap_send_flags_t;
 
 struct coap_queue_t;
 
@@ -71,6 +74,7 @@ typedef struct coap_queue_t {
   coap_pdu_t *pdu;      /**< the CoAP PDU to send */
 
   unsigned char delayedResponse;  /**< delayed response flag */
+  unsigned char secure;      /**< rx/tx will use secure channel (DTLS) */
 } coap_queue_t;
 
 /** Adds node to given queue, ordered by node->t. */
@@ -298,11 +302,13 @@ coap_pdu_t *coap_new_error_response(coap_pdu_t *request,
  * @param context The CoAP context to use.
  * @param dst     The address to send to.
  * @param pdu     The CoAP PDU to send.
- * @param flag    The flag indicating if the message will be sent with delay
+ * @param flag    The flag indicating how the message will be send
  * @return The message id of the sent message or @c COAP_INVALID_TID on error.
  */
 
-coap_tid_t coap_send(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *pdu, const uint8_t flag);
+coap_tid_t coap_send(coap_context_t *context, const coap_address_t *dst,
+                 coap_pdu_t *pdu,
+                 coap_send_flags_t flag);
 
 /**
  * Sends an error response with code @p code for request @p request to
@@ -325,7 +331,8 @@ coap_tid_t coap_send_error(coap_context_t *context,
                coap_pdu_t *request,
                const coap_address_t *dst,
                unsigned char code,
-               coap_opt_filter_t opts);
+               coap_opt_filter_t opts,
+               coap_send_flags_t flag);
 
 /**
  * Helper funktion to create and send a message with @p type (usually
@@ -336,12 +343,14 @@ coap_tid_t coap_send_error(coap_context_t *context,
  * @param dst Where to send the context.
  * @param request The request that should be responded to.
  * @param type Which type to set
+ * @param flag options for sending the message
  * @return transaction id on success or @c COAP_INVALID_TID otherwise.
  */
 coap_tid_t
 coap_send_message_type(coap_context_t *context,
                const coap_address_t *dst,
                coap_pdu_t *request,
+               coap_send_flags_t flag,
                unsigned char type);
 /**
  * Sends an ACK message with code @c 0 for the specified @p request to
@@ -351,13 +360,15 @@ coap_send_message_type(coap_context_t *context,
  * @param context The context to use.
  * @param dst     The destination address.
  * @param request The request to be acknowledged.
+ * @param flag    Options for sending the acknowledgement.
  *
  * @return The transaction id if ACK was sent or @c COAP_INVALID_TID
  * on error.
  */
 coap_tid_t coap_send_ack(coap_context_t *context,
              const coap_address_t *dst,
-             coap_pdu_t *request);
+             coap_pdu_t *request,
+             coap_send_flags_t flag);
 
 /**
  * Sends an RST message with code @c 0 for the specified @p request to
@@ -367,6 +378,7 @@ coap_tid_t coap_send_ack(coap_context_t *context,
  * @param context The context to use.
  * @param dst     The destination address.
  * @param request The request to be reset.
+ * @param flag    Options for sending the reset message.
  *
  * @return The transaction id if RST was sent or @c COAP_INVALID_TID
  * on error.
@@ -374,8 +386,9 @@ coap_tid_t coap_send_ack(coap_context_t *context,
 static inline coap_tid_t
 coap_send_rst(coap_context_t *context,
           const coap_address_t *dst,
-          coap_pdu_t *request) {
-  return coap_send_message_type(context, dst, request, COAP_MESSAGE_RST);
+          coap_pdu_t *request,
+          coap_send_flags_t flag) {
+  return coap_send_message_type(context, dst, request, flag, COAP_MESSAGE_RST);
 }
 
 /** Handles retransmissions of confirmable messages */
index 273a9d8..56a99ca 100644 (file)
@@ -58,7 +58,7 @@ GenerateCoAPPdu(uint8_t msgType, uint8_t code, unsigned short id,
 // Internal function to send a coap pdu, it also handles NON and CON
 OCStackResult
 SendCoAPPdu(coap_context_t * gCoAPCtx, coap_address_t* dst, coap_pdu_t * pdu,
-        uint8_t delayFlag);
+        coap_send_flags_t flag);
 
 // Call back function used by libcoap to order option in coap pdu
 int OrderOptions(void *a, void *b);
index 765d571..4081675 100644 (file)
@@ -144,6 +144,7 @@ static void HandleCoAPRequests(struct coap_context_t *ctx,
     uint8_t * rcvObserveOption = NULL;
     unsigned char * bufReqPayload = NULL;
     uint32_t observeOption = OC_RESOURCE_NO_OBSERVE;
+    coap_send_flags_t sendFlag;
     memset(&entityHandlerRequest, 0, sizeof(OCEntityHandlerRequest));
 
     coap_pdu_t * recvPdu = rcvdRequest->pdu;
@@ -184,7 +185,7 @@ static void HandleCoAPRequests(struct coap_context_t *ctx,
             }
         default:
             {
-                OC_LOG_V(ERROR, TAG, "Received CoAP method %d not supported", 
+                OC_LOG_V(ERROR, TAG, "Received CoAP method %d not supported",
                          recvPdu->hdr->code);
                 goto exit;
             }
@@ -278,7 +279,11 @@ static void HandleCoAPRequests(struct coap_context_t *ctx,
     VERIFY_NON_NULL(sendPdu);
     coap_show_pdu(sendPdu);
 
-    if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) &(rcvdRequest->remote), sendPdu, rcvdRequest->delayedResponse)
+    sendFlag = (coap_send_flags_t)(rcvdRequest->delayedResponse ? SEND_DELAYED : 0);
+    sendFlag = (coap_send_flags_t)( sendFlag | (rcvdRequest->secure ? SEND_SECURE_PORT : 0));
+
+    if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) &(rcvdRequest->remote), sendPdu,
+         sendFlag)
             != OC_STACK_OK){
         OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));
     }
@@ -404,7 +409,8 @@ static void HandleCoAPResponses(struct coap_context_t *ctx,
                         recvPdu->hdr->id, NULL, NULL, NULL);
                 VERIFY_NON_NULL(sendPdu);
                 result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote,
-                        sendPdu, 0);
+                        sendPdu,
+                        (coap_send_flags_t)(rcvdResponse->secure ? SEND_SECURE_PORT : 0));
             }
             //TODO: check the standard for methods to detect wrap around condition
             if(cbNode->method == OC_REST_OBSERVE &&
@@ -481,7 +487,8 @@ static void HandleCoAPResponses(struct coap_context_t *ctx,
         sendPdu = GenerateCoAPPdu(COAP_MESSAGE_RST, 0,
                 recvPdu->hdr->id, NULL, NULL, NULL);
         VERIFY_NON_NULL(sendPdu);
-        result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote, sendPdu, 0);
+        result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote, sendPdu,
+                     (coap_send_flags_t)(rcvdResponse->secure ? SEND_SECURE_PORT : 0));
         VERIFY_SUCCESS(result, OC_STACK_OK);
     }
     #ifdef WITH_PRESENCE
@@ -498,7 +505,8 @@ static void HandleCoAPResponses(struct coap_context_t *ctx,
         sendPdu = GenerateCoAPPdu(COAP_MESSAGE_RST, 0,
                 recvPdu->hdr->id, NULL, NULL, NULL);
         VERIFY_NON_NULL(sendPdu);
-        result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote, sendPdu, 0);
+        result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote, sendPdu,
+                    (coap_send_flags_t)(rcvdResponse->secure ? SEND_SECURE_PORT : 0));
         VERIFY_SUCCESS(result, OC_STACK_OK);
     }
     exit:
@@ -609,6 +617,7 @@ OCStackResult OCDoCoAPResource(OCMethod method, OCQualityOfService qos, OCCoAPTo
     uint8_t coapMsgType;
     uint8_t coapMethod;
     uint32_t observeOption;
+    coap_send_flags_t flag = (coap_send_flags_t)0;
 
     OC_LOG(INFO, TAG, PCF("Entering OCDoCoAPResource"));
 
@@ -628,6 +637,8 @@ OCStackResult OCDoCoAPResource(OCMethod method, OCQualityOfService qos, OCCoAPTo
                 (uint16_t*)&uri.port, uri.path.length, uri.path.s, uri.query.length,
                 uri.query.s, options, numOptions), OC_STACK_OK);
 
+        //TODO : Investigate the scenario where there will be no uri for OCDoCoAPResource
+        //flag = (coap_send_flags_t) (uri.secure ? SEND_SECURE_PORT : 0);
         OC_LOG_V(DEBUG, TAG, "uri.host.s %s", uri.host.s);
         OC_LOG_V(DEBUG, TAG, "uri.path.s %s", uri.path.s);
         OC_LOG_V(DEBUG, TAG, "uri.port %d", uri.port);
@@ -674,7 +685,7 @@ OCStackResult OCDoCoAPResource(OCMethod method, OCQualityOfService qos, OCCoAPTo
             (unsigned char*) payload, optList);
     VERIFY_NON_NULL(pdu);
 
-    ret = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &dst, pdu, 0);
+    ret = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &dst, pdu, flag);
 
 exit:
     if (ret!= OC_STACK_OK)
@@ -726,8 +737,10 @@ OCStackResult OCSendCoAPNotification (unsigned char * uri, OCDevAddr *dstAddr,
     VERIFY_NON_NULL(sendPdu);
     coap_show_pdu(sendPdu);
 
-    if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) dstAddr, sendPdu, 0)
-            != OC_STACK_OK){
+    // TODO : resourceProperties will determine if the packet will be send using secure port
+    if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) dstAddr, sendPdu , (coap_send_flags_t)0 )
+            != OC_STACK_OK)
+    {
         OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));
     }
     return OC_STACK_OK;
index 829e807..7ad7e53 100644 (file)
@@ -555,29 +555,18 @@ OCStackResult FormOptionList(coap_list_t * * optListLoc, uint8_t * addMediaType,
 //Send a coap pdu
 OCStackResult
 SendCoAPPdu(coap_context_t * gCoAPCtx, coap_address_t* dst, coap_pdu_t * pdu,
-        uint8_t delayFlag)
+        coap_send_flags_t flag)
 {
     coap_tid_t tid = COAP_INVALID_TID;
     OCStackResult res = OC_STACK_COMM_ERROR;
-    uint8_t sendFlag = SEND_NOW;
 
-    if(delayFlag)
+    if (!(flag & SEND_DELAYED))
     {
-        sendFlag = SEND_DELAYED;
-    }
-    else
-    {
-        if(pdu->hdr->type != COAP_MESSAGE_CON)
-        {
-            sendFlag = SEND_NOW;
-        }
-        else
-        {
-            sendFlag = SEND_NOW_CON;
-        }
+        flag = (coap_send_flags_t)( flag |
+            (pdu->hdr->type == COAP_MESSAGE_CON) ? SEND_NOW_CON : SEND_NOW);
     }
 
-    tid = coap_send(gCoAPCtx, dst, pdu, sendFlag);
+    tid = coap_send(gCoAPCtx, dst, pdu, flag);
     OC_LOG_V(INFO, TAG, "TID %d", tid);
     if(tid != COAP_INVALID_TID)
     {
@@ -586,7 +575,7 @@ SendCoAPPdu(coap_context_t * gCoAPCtx, coap_address_t* dst, coap_pdu_t * pdu,
         res = OC_STACK_OK;
     }
 
-    if ((pdu->hdr->type != COAP_MESSAGE_CON && !delayFlag) || tid == COAP_INVALID_TID)
+    if ((pdu->hdr->type != COAP_MESSAGE_CON && (!(flag & SEND_DELAYED))) || tid == COAP_INVALID_TID)
     {
         OC_LOG(INFO, TAG, PCF("Deleting PDU"));
         coap_delete_pdu(pdu);
@@ -779,7 +768,8 @@ void HandleSendQueue(coap_context_t * ctx)
         {
             OC_LOG_V(DEBUG, TAG, "Sending Delayed response TID %d",
                     nextQueue->id);
-            if(SendCoAPPdu(ctx, &nextQueue->remote, nextQueue->pdu, 0)
+            if(SendCoAPPdu(ctx, &nextQueue->remote, nextQueue->pdu,
+                 (coap_send_flags_t)(nextQueue->secure ? SEND_SECURE_PORT : 0))
                     == OC_STACK_COMM_ERROR)
             {
                 OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));