Documentation

Documentation.Development-Manual-API-Lumps-3-1 History

Hide minor edits - Show changes to markup

December 11, 2019, at 06:48 PM by liviu -
Changed line 22 from:

SIP Message Lumps

to:

SIP Request Lumps

December 11, 2019, at 06:47 PM by liviu -
Changed lines 22-23 from:
SIP Message Lumps
to:

SIP Message Lumps

Changed lines 28-29 from:
Delete Lumps
to:
Delete Lumps
Changed lines 61-62 from:
Add Lumps
to:
Add Lumps
Changed line 162 from:
SIP Reply Lumps
to:

SIP Reply Lumps

December 11, 2019, at 06:46 PM by liviu -
Added lines 1-190:
Documentation -> Development Manual 3.1 -> Changing SIP Messages

This page has been visited 1666 times. (:title OpenSIPS Development - Changing SIP Messages:)


(:allVersions Development-Manual-API-Lumps 3.1:)


Changing SIP Messages

(:toc-float Table of Content:)

Changing SIP Messages

The standard mechanism for performing changes on SIP messages within OpenSIPS is by using the so called lumps system.
The lump system works very similarly to the diff/patch tools in the Linux environment – the developer adds add and/or remove operations to a SIP message. The lumps are stored in a list, and are only applied after the OpenSIPS script is fully executed and before the SIP message is relayed. Because of this, changes done on a SIP message are not immediately reflected on the SIP message upon further inspection ( eg. Adding a new header from the script and then checking for the header's existence ).
When talking about the SIP message they have an effect on, the lumps can be split into the following categories :

SIP Message Lumps

This type of lumps operate on the current SIP message context.
From operational point of view, they are also split into two categories :

Delete Lumps

data_lump.h exposes

(:source lang=C -link -getcode :) /* Parameters :

      msg - the SIP message the lump will affect
      offset - the offset in the SIP message at which to start deleting
      len - the number of characters to delete from the SIP message
      type - indication on which header the current lump affects ( can be 0 )

Returns :

      the created lump structure for deleting part of the SIP message. Can be further used to chain together different types of lumps in the message attached list of lumps. NULL is returned in case of internal error.
  • /

struct lump* del_lump(struct sip_msg* msg, unsigned int offset,

        unsigned int len, enum _hdr_types_t type); 

(:sourceend:)
Example of deleting the RPID header : (:source lang=C -link -getcode :)

      /* first parse the header to figure out where it actually starts in the SIP message */
      if( parse_headers(msg,HDR_RPID_F,0)<0 || msg->rpid == NULL ){ 
            LM_DBG(“No rpid header – nothing to delete \n”);
	    return 0;
      }

      /* delete the entire RPID header */
      if ( del_lump(msg, msg->rpid->name.s-msg->buf, msg->rpid->len,HDR_RPID_T )== NULL) {
            LM_ERR(“Failed to delete RPID header \n”);
	    return -1;
      }

(:sourceend:)

Add Lumps

data_lump.h exposes

(:source lang=C -link -getcode :) /* Parameters :

      after/before - the lump where we will connect our new lump
      new_hdr - string to be added
      len - length of the string to be added
      type - header type that is affected by the current change ( can be 0 )

Returns :

      the created lump structure for adding to the SIP message. Can be further used to chain together different types of lumps in the message attached list of lumps. NULL is returned in case of internal error.
  • /

struct lump* insert_new_lump_after(struct lump* after,

                char* new_hdr, unsigned int len, enum _hdr_types_t type);                                        

struct lump* insert_new_lump_before(struct lump* before, char* new_hdr,

                unsigned int len,enum _hdr_types_t type);

(:sourceend:)
If the developer's desire is just to add a particular string to the SIP message, a new anchor lump must be created, that will then have to be provided as the first parameter to insert_new_lump_after/insert_new_lump_before.
For creating a new anchor lump, data_lump.h also exports (:source lang=C -link -getcode :) /* Parameters :

      msg - the SIP message that will be affected by the lump anchor
      offset - the offset in the SIP message where the anchor will be placed
      len - not currently used ( should be 0 )
      type - header type that is affected by the current change ( can be 0 )

Returns:

      the created lump structure for adding to the SIP message. Can be further used to chain together different types of lumps in the message attached list of lumps. NULL is returned in case of internal error.
  • /

struct lump* anchor_lump(struct sip_msg* msg, unsigned int offset,

                int unsigned len, enum _hdr_types_t type) 

(:sourceend:)
Example of adding a new SIP header at the end of the SIP message headers : (:source lang=C -link -getcode :)

      /* make sure we detect all headers */
      if (parse_headers(msg, HDR_EOH_F, 0) == -1) { 
            LM_ERR("error while parsing message\n"); 
            return -1; 
      } 

      /* add the anchor at the very end of the SIP headers */
      anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0);
      if (anchor == NULL) {
            LM_ERR(“Failed to create lump anchor\n”);
	    return -1;
      }
      len =  sizeof(“MY_HDR: MY_VAL\r\n”) -1;
      new_hdr=pkg_malloc(len);
      if (!new_hdr) {
            LM_ERR(“No more pkg mem\n”);
	    return -1;
      }

      memcpy(new_hdr,”MY_HDR: MY_VAL\r\n”,len);
      if (insert_new_lump_after(anchor, new_hdr, len, 0) == 0) { 
            LM_ERR("can't insert lump\n"); 
            pkg_free(new_hdr); 
            return -1; 
      } 

      /* job done, the PKG new_hdr mem will be free internally when the lump will be applied */
      return 0;

(:sourceend:)

If we want to replace a particular part of a SIP message, the operation can be split in two steps, first deleting the part we don't need anymore by calling del_lump, and then using the returned lump to add a new lump after it.
Example of replacing the content of the RPID header : (:source lang=C -link -getcode :)

      /* first parse the header to figure out where it actually starts in the SIP message */
      if( parse_headers(msg,HDR_RPID_F,0)<0 || msg->rpid == NULL ){ 
            LM_DBG(“No rpid header – nothing to delete \n”);
	    return 0;
      }

      /* delete just the contents of the RPID header */
      del =  del_lump(msg, msg->rpid->body.s-msg->buf, msg->rpid->body.len,HDR_RPID_T);
      if ( del == NULL) {
            LM_ERR(“Failed to delete RPID header \n”);
	    return -1;
      }

      len =  sizeof(“sip:new_rpid@my_domain.com\r\n”) -1;
      new_rpid=pkg_malloc(len);
      if (!new_rpid) {
            LM_ERR(“No more pkg mem\n”);
	    return -1;
      }
      memcpy(new_rpid,“sip:new_rpid@my_domain.com\r\n”,len);

      if(insert_new_lump_after(del,new_rpid,len,HDR_RPID_T)==NULL) { 
            LM_ERR("Failed to insert new callid\n"); 
            pkg_free(new_rpid); 
            return -1; 
      } 

(:sourceend:)

SIP Reply Lumps

When used in the case of a SIP request, these lumps will operate on the SIP reply that will be internally generated when rejecting a request from within OpenSIPS ( if the Request if forwarded instead of rejected at OpenSIPS level, these lumps will have no effect ). Since the reply will be internally generated by OpenSIPS, the Reply Lumps can only add new content.
data_lump_rpl.h exposes (:source lang=C -link -getcode :) /* Parameters :

      msg - the SIP Request that the reply will be generated for
      s - the string to be added to the reply
      len - the length of the string to be added
      flags - Since the reply will be generated by OpenSIPS, it is important to mark your lump if it should be added to the Reply headers or to the Reply body. Relevant flags for these cases are LUMP_RPL_HDR and LUMP_RPL_BODY.

Returns :

      the created lump structure for adding to the SIP reply. Can be further used to chain together lumps in the message attached list of lumps. NULL is returned in case of internal error.
  • /

struct lump_rpl* add_lump_rpl(struct sip_msg *msg, char *s, int len, int flags); (:sourceend:)
Example of Adding contact header to the internally generated reply : (:source lang=C -link -getcode :)

      static char ct[CT_LEN] = “Contact: opensips@my_domain.com\r\n”;

      /* we are adding a lump to the headers, so we pass the  LUMP_RPL_HDR flag
      also , our buffer is located in a static buffer, thus no need for the core to allocate memory for this lump, we also pass the LUMP_RPL_NODUP flag */
      if (add_lump_rpl(msg, ct, CT_LEN, LUMP_RPL_HDR |  LUMP_RPL_NODUP)==0) { 
            LM_ERR("unable to add lump\n"); 
            return -1; 
      } 

(:sourceend:)


Page last modified on December 11, 2019, at 06:48 PM