parse_sst.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "parse_sst.h"
00034
00035 #include "../error.h"
00036 #include "../dprint.h"
00037 #include "../mem/mem.h"
00038
00039
00040 inline int is_space( char c ) { return (c == ' ' || c == '\t'); }
00041 inline int is_num( char c ) { return (c >= '0' && c <= '9'); }
00042
00043 inline unsigned lower_byte( char b ) { return b | 0x20; }
00044 inline unsigned lower_4bytes( unsigned d ) { return d | 0x20202020; }
00045 inline unsigned lower_3bytes( unsigned d ) { return d | 0x202020; }
00046 inline unsigned read_4bytes( char *val ) {
00047 return (*(val + 0) + (*(val + 1) << 8)
00048 + (*(val + 2) << 16) + (*(val + 3) << 24));
00049 }
00050 inline unsigned read_3bytes( char *val ) {
00051 return (*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16));
00052 }
00053
00054
00055 #define MAKE_4BYTES( a, b, c, d ) \
00056 ( ((a)&0xFF) | (((b)&0xFF)<<8) | (((c)&0xFF)<<16) | (((d)&0xFF)<<24) )
00057 #define MAKE_3BYTES( a, b, c ) \
00058 ( ((a)&0xFF) | (((b)&0xFF)<<8) | (((c)&0xFF)<<16) )
00059
00060
00061 struct session_expires *
00062 malloc_session_expires( void )
00063 {
00064 struct session_expires *se = (struct session_expires *)
00065 pkg_malloc( sizeof(struct session_expires) );
00066 if ( se )
00067 memset( se, 0, sizeof(struct session_expires) );
00068 return se;
00069 }
00070
00071
00072 void
00073 free_session_expires( struct session_expires *se )
00074 {
00075 if ( se )
00076 pkg_free( se );
00077 }
00078
00079
00080 enum parse_sst_result
00081 parse_session_expires_body( struct hdr_field *hf )
00082 {
00083 register char *p = hf->body.s;
00084 int pos = 0;
00085 int len = hf->body.len;
00086 char *q;
00087 struct session_expires se = { 0, sst_refresher_unspecified };
00088 unsigned tok;
00089
00090 if ( !p || len <= 0 ) {
00091 LM_ERR(" no body for header field\n" );
00092 return parse_sst_header_not_found;
00093 }
00094
00095
00096 for ( ; pos < len && is_space(*p); ++pos, ++p )
00097 ;
00098
00099
00100 for ( q = p; pos < len && is_num(*q); ++pos, ++q )
00101 se.interval = se.interval*10 + (*q - '0');
00102
00103 if ( q == p ) {
00104 LM_ERR(" no expiry interval\n" );
00105 return parse_sst_no_value;
00106 }
00107 p = q;
00108
00109
00110 while ( pos < len ) {
00111
00112 if ( *p == ';' ) {
00113 ++p; ++pos;
00114
00115 if ( pos + 4 < len ) {
00116 switch ( lower_4bytes(read_4bytes(p)) ) {
00117 case MAKE_4BYTES('r','e','f','r'):
00118 if ( pos + 9 <= len
00119 && lower_4bytes(read_4bytes(p+4))
00120 == MAKE_4BYTES('e','s','h','e')
00121 && lower_byte(*(p+8)) == 'r'
00122 && *(p+9) == '=' ) {
00123 tok = lower_3bytes( read_3bytes(p+10) );
00124 if ( tok == MAKE_3BYTES('u','a','c') ) {
00125 se.refresher = sst_refresher_uac;
00126 p += 13; pos += 13;
00127 }
00128 else if ( tok == MAKE_3BYTES('u','a','s') ) {
00129 se.refresher = sst_refresher_uas;
00130 p += 13; pos += 13;
00131 }
00132 else {
00133 LM_ERR(" unrecognized refresher\n" );
00134 return parse_sst_parse_error;
00135 }
00136 }
00137 else {
00138
00139
00140 for ( ; pos < len && *p != ';'; ++pos, ++p )
00141 ;
00142 }
00143 break;
00144 default:
00145
00146 for ( ; pos < len && *p != ';'; ++pos, ++p )
00147 ;
00148 break;
00149 }
00150 }
00151 else {
00152
00153
00154 for ( ; pos < len && *p != ';'; ++pos, ++p ) ;
00155 }
00156 }
00157 else {
00158 LM_ERR("no semicolon separating se-params\n");
00159 return parse_sst_parse_error;
00160 }
00161 }
00162
00163 hf->parsed = malloc_session_expires();
00164 if ( !hf->parsed ) {
00165 LM_ERR(" out of pkg memory\n" );
00166 return parse_sst_out_of_mem;
00167 }
00168 *((struct session_expires *)hf->parsed) = se;
00169
00170 return parse_sst_success;
00171 }
00172
00173
00174 enum parse_sst_result
00175 parse_session_expires( struct sip_msg *msg, struct session_expires *se )
00176 {
00177 enum parse_sst_result result;
00178
00179 if ( msg->session_expires ) {
00180 if ( msg->session_expires->parsed == 0
00181 && (result = parse_session_expires_body(msg->session_expires))
00182 != parse_sst_success ) {
00183 return result;
00184 }
00185 if ( se ) {
00186 *se = *((struct session_expires *)msg->session_expires->parsed);
00187 }
00188 return parse_sst_success;
00189 }
00190 else {
00191 return parse_sst_header_not_found;
00192 }
00193 }
00194
00195
00196 enum parse_sst_result
00197 parse_min_se_body( struct hdr_field *hf )
00198 {
00199 int len = hf->body.len;
00200 char *p = hf->body.s;
00201 int pos = 0;
00202 unsigned int interval = 0;
00203
00204
00205 for ( ; pos < len && is_space(*p); ++pos, ++p )
00206 ;
00207 if ( pos == len )
00208 return parse_sst_no_value;
00209
00210 for ( ; pos < len && is_num(*p); ++pos, ++p )
00211 interval = interval*10 + (*p - '0');
00212
00213 for ( ; pos < len && is_space(*p); ++pos, ++p )
00214 ;
00215 if ( pos != len )
00216 return parse_sst_parse_error;
00217 hf->parsed=(void*)(long)interval;
00218 return parse_sst_success;
00219 }
00220
00221
00222 enum parse_sst_result
00223 parse_min_se( struct sip_msg *msg, unsigned int *min_se )
00224 {
00225 enum parse_sst_result result;
00226
00227 if ( msg->min_se ) {
00228 if ( msg->min_se->parsed == 0
00229 && (result = parse_min_se_body(msg->min_se))
00230 != parse_sst_success ) {
00231 return result;
00232 }
00233 if ( min_se ) {
00234 *min_se = (unsigned int)(long)msg->min_se->parsed;
00235 }
00236 return parse_sst_success;
00237 }
00238 else {
00239 return parse_sst_header_not_found;
00240 }
00241 }