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
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
00074 void hf_free_session_expires(void *parsed)
00075 {
00076 struct session_expires *se;
00077 se = (struct session_expires*)parsed;
00078 free_session_expires(se);
00079 }
00080
00081
00082 void
00083 free_session_expires( struct session_expires *se )
00084 {
00085 if ( se )
00086 pkg_free( se );
00087 }
00088
00089
00090 enum parse_sst_result
00091 parse_session_expires_body( struct hdr_field *hf )
00092 {
00093 register char *p = hf->body.s;
00094 int pos = 0;
00095 int len = hf->body.len;
00096 char *q;
00097 struct session_expires se = { 0, 0, sst_refresher_unspecified };
00098 unsigned tok;
00099
00100 if ( !p || len <= 0 ) {
00101 LM_ERR(" no body for header field\n" );
00102 return parse_sst_header_not_found;
00103 }
00104
00105
00106 for ( ; pos < len && is_space(*p); ++pos, ++p )
00107 ;
00108
00109
00110 for ( q = p; pos < len && is_num(*q); ++pos, ++q )
00111 se.interval = se.interval*10 + (*q - '0');
00112
00113 if ( q == p ) {
00114 LM_ERR(" no expiry interval\n" );
00115 return parse_sst_no_value;
00116 }
00117 p = q;
00118
00119
00120 while ( pos < len ) {
00121
00122 if ( *p == ';' ) {
00123 ++p; ++pos;
00124
00125 if ( pos + 4 < len ) {
00126 switch ( lower_4bytes(read_4bytes(p)) ) {
00127 case MAKE_4BYTES('r','e','f','r'):
00128 if ( pos + 9 <= len
00129 && lower_4bytes(read_4bytes(p+4))
00130 == MAKE_4BYTES('e','s','h','e')
00131 && lower_byte(*(p+8)) == 'r'
00132 && *(p+9) == '=' ) {
00133 tok = lower_3bytes( read_3bytes(p+10) );
00134 if ( tok == MAKE_3BYTES('u','a','c') ) {
00135 se.refresher = sst_refresher_uac;
00136 p += 13; pos += 13;
00137 }
00138 else if ( tok == MAKE_3BYTES('u','a','s') ) {
00139 se.refresher = sst_refresher_uas;
00140 p += 13; pos += 13;
00141 }
00142 else {
00143 LM_ERR(" unrecognized refresher\n" );
00144 return parse_sst_parse_error;
00145 }
00146 }
00147 else {
00148
00149
00150 for ( ; pos < len && *p != ';'; ++pos, ++p )
00151 ;
00152 }
00153 break;
00154 default:
00155
00156 for ( ; pos < len && *p != ';'; ++pos, ++p )
00157 ;
00158 break;
00159 }
00160 }
00161 else {
00162
00163
00164 for ( ; pos < len && *p != ';'; ++pos, ++p ) ;
00165 }
00166 }
00167 else {
00168 LM_ERR("no semicolon separating se-params\n");
00169 return parse_sst_parse_error;
00170 }
00171 }
00172
00173 hf->parsed = malloc_session_expires();
00174 if ( !hf->parsed ) {
00175 LM_ERR(" out of pkg memory\n" );
00176 return parse_sst_out_of_mem;
00177 }
00178 se.hfree = hf_free_session_expires;
00179 *((struct session_expires *)hf->parsed) = se;
00180
00181 return parse_sst_success;
00182 }
00183
00184
00185 enum parse_sst_result
00186 parse_session_expires( struct sip_msg *msg, struct session_expires *se )
00187 {
00188 enum parse_sst_result result;
00189
00190 if ( msg->session_expires ) {
00191 if ( msg->session_expires->parsed == 0
00192 && (result = parse_session_expires_body(msg->session_expires))
00193 != parse_sst_success ) {
00194 return result;
00195 }
00196 if ( se ) {
00197 *se = *((struct session_expires *)msg->session_expires->parsed);
00198 }
00199 return parse_sst_success;
00200 }
00201 else {
00202 return parse_sst_header_not_found;
00203 }
00204 }
00205
00206
00207 enum parse_sst_result
00208 parse_min_se_body( struct hdr_field *hf )
00209 {
00210 int len = hf->body.len;
00211 char *p = hf->body.s;
00212 int pos = 0;
00213 unsigned int interval = 0;
00214
00215
00216 for ( ; pos < len && is_space(*p); ++pos, ++p )
00217 ;
00218 if ( pos == len )
00219 return parse_sst_no_value;
00220
00221 for ( ; pos < len && is_num(*p); ++pos, ++p )
00222 interval = interval*10 + (*p - '0');
00223
00224 for ( ; pos < len && is_space(*p); ++pos, ++p )
00225 ;
00226 if ( pos != len )
00227 return parse_sst_parse_error;
00228 hf->parsed=(void*)(long)interval;
00229 return parse_sst_success;
00230 }
00231
00232
00233 enum parse_sst_result
00234 parse_min_se( struct sip_msg *msg, unsigned int *min_se )
00235 {
00236 enum parse_sst_result result;
00237
00238 if ( msg->min_se ) {
00239 if ( msg->min_se->parsed == 0
00240 && (result = parse_min_se_body(msg->min_se))
00241 != parse_sst_success ) {
00242 return result;
00243 }
00244 if ( min_se ) {
00245 *min_se = (unsigned int)(long)msg->min_se->parsed;
00246 }
00247 return parse_sst_success;
00248 }
00249 else {
00250 return parse_sst_header_not_found;
00251 }
00252 }