8dd2331c8c60e14fc67e6639b2d2c54c59af8876
[sip-router] / parser / parse_hname2.c
1 /*
2  * $Id$
3  */
4
5
6 #include "parse_hname2.h"
7 #include "keys.h"
8 #include "../ut.h"  /* q_memchr */
9
10 /*
11  * Size of hash table, this is magic value
12  * that ensures, that there are no synonyms for
13  * frequently used keys (frequently used keys are
14  * 4-byte parts of message headers we recognize)
15  * WARNING ! This value MUST be recalculated if you want
16  * a new header to be recognized
17  */
18 #define HASH_TABLE_SIZE 9349
19
20
21 /*
22  * Hash function
23  */
24 #define HASH_FUNC(val) ((val) % HASH_TABLE_SIZE)
25
26
27 /*
28  * This constants marks empty hash table element
29  */
30 #define HASH_EMPTY 0x2d2d2d2d
31
32
33 /*
34  * Hash table entry
35  */
36 struct ht_entry {
37         unsigned int key;
38         unsigned int value;
39 };
40
41
42 static struct ht_entry hash_table[HASH_TABLE_SIZE];
43
44
45 /*
46  * Pointer to the hash table
47  */
48 /*
49 static struct ht_entry *hash_table;
50 */
51
52
53 /*
54  * Declarations
55  */
56 static inline char* skip_ws     (char* p, unsigned int size);
57 void                init_htable (void);
58 static void         set_entry   (unsigned int key, unsigned int val);
59 static inline int   unify       (int key);
60
61
62 /*
63  * Skip all whitechars and return position of the first
64  * non-white char
65  */
66 static inline char* skip_ws(char* p, unsigned int size)
67 {
68         char* end;
69         
70         end = p + size;
71         for(; p < end; p++) {
72                 if ((*p != ' ') && (*p != '\t')) return p;
73         }
74         return p;
75 }
76         
77
78 /*
79  * Used to initialize hash table
80  */
81 static void set_entry(unsigned int key, unsigned int val)
82 {
83         hash_table[HASH_FUNC(key)].key = key;
84         hash_table[HASH_FUNC(key)].value = val;
85 }
86
87
88 /*
89  * cSeQ -> CSeq and so on...
90  */ 
91 static inline int unify(int key)
92 {
93         register struct ht_entry* en;
94
95         en = &hash_table[HASH_FUNC(key)];
96         if (en->key == key) {
97                 return en->value;
98         } else {
99                 return key;
100         }
101 }
102
103
104 /*
105  * Parser macros
106  */
107 #include "case_via.h"      /* Via */
108 #include "case_from.h"     /* From */
109 #include "case_to.h"       /* To */
110 #include "case_cseq.h"     /* CSeq */
111 #include "case_call.h"     /* Call-ID */
112 #include "case_cont.h"     /* Contact, Content-Type, Content-Length */
113 #include "case_rout.h"     /* Route */
114 #include "case_max.h"      /* Max-Forwards */
115 #include "case_reco.h"     /* Record-Route */
116 #include "case_auth.h"     /* Authorization */
117 #include "case_expi.h"     /* Expires */
118 #include "case_prox.h"     /* Proxy-Authorization, Proxy-Require */
119 #include "case_allo.h"     /* Allow */
120 #include "case_unsu.h"     /* Unsupported */
121 #include "case_requ.h"     /* Require */
122 #include "case_supp.h"     /* Supported */
123 #include "case_www.h"      /* WWW-Authenticate */
124 #include "case_even.h"     /* Event */
125
126
127 #define READ(val) \
128 (*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
129
130
131 #define FIRST_QUATERNIONS       \
132         case _Via1_: Via1_CASE; \
133         case _From_: From_CASE; \
134         case _To12_: To12_CASE; \
135         case _CSeq_: CSeq_CASE; \
136         case _Call_: Call_CASE; \
137         case _Cont_: Cont_CASE; \
138         case _Rout_: Rout_CASE; \
139         case _Max__: Max_CASE;  \
140         case _Reco_: Reco_CASE; \
141         case _Via2_: Via2_CASE; \
142         case _Auth_: Auth_CASE; \
143         case _Expi_: Expi_CASE; \
144         case _Prox_: Prox_CASE; \
145         case _Allo_: Allo_CASE; \
146         case _Unsu_: Unsu_CASE; \
147         case _Requ_: Requ_CASE; \
148         case _Supp_: Supp_CASE; \
149         case _WWW__: WWW_CASE;  \
150         case _Even_: Even_CASE;
151
152
153 #define PARSE_COMPACT(id)          \
154         switch(*(p + 1)) {         \
155         case ' ':                  \
156                 hdr->type = id;    \
157                 p += 2;            \
158                 goto dc_end;       \
159                                    \
160         case ':':                  \
161                 hdr->type = id;    \
162                 hdr->name.len = 1; \
163                 *(p + 1) = '\0';   \
164                 return (p + 2);    \
165         }                            
166
167
168 char* parse_hname2(char* begin, char* end, struct hdr_field* hdr)
169 {
170         register char* p;
171         register int val;
172
173         p = begin;
174         val = READ(p);
175         hdr->name.s = begin;
176
177         if ((end - begin) < 4) {
178                 hdr->type = HDR_ERROR;
179                 return begin;
180         }
181
182         switch(val) {
183         FIRST_QUATERNIONS;
184
185         default:
186                 switch(*p) {
187                 case 'T':                           
188                 case 't':                           
189                         switch(*(p + 1)) {          
190                         case 'o':                   
191                         case 'O':                   
192                         case ' ':                   
193                                 hdr->type = HDR_TO; 
194                                 p += 2;             
195                                 goto dc_end;        
196                                 
197                         case ':':                   
198                                 hdr->type = HDR_TO; 
199                                 hdr->name.len = 1;  
200                                 *(p + 1) = '\0'; 
201                                 return (p + 2);     
202                         }                           
203                         break;
204
205                 case 'V':                            
206                 case 'v':                            
207                         PARSE_COMPACT(HDR_VIA);
208                         break;
209                         
210                 case 'F':
211                 case 'f':
212                         PARSE_COMPACT(HDR_FROM);
213                         break;
214                         
215                 case 'I':
216                 case 'i':
217                         PARSE_COMPACT(HDR_CALLID);
218                         break;
219
220                 case 'M':
221                 case 'm':
222                         PARSE_COMPACT(HDR_CONTACT);
223                         break;
224
225                 case 'L':
226                 case 'l':
227                         PARSE_COMPACT(HDR_CONTENTLENGTH);
228                         break;
229
230                 case 'C':
231                 case 'c':
232                         PARSE_COMPACT(HDR_CONTENTTYPE);
233                         break;
234
235                 case 'K':
236                 case 'k':
237                         PARSE_COMPACT(HDR_SUPPORTED);
238                         break;
239
240                 case 'O':
241                 case 'o':
242                         PARSE_COMPACT(HDR_EVENT);
243                         break;
244                 }
245                 
246                 val = unify(val);
247                 switch(val) {
248                 FIRST_QUATERNIONS;
249                 default: goto other;
250                 }
251         }
252
253              /* Double colon hasn't been found yet */
254  dc_end:
255         p = skip_ws(p, end - p);
256         if (*p != ':') {   
257                 goto other;
258         } else {
259                 hdr->name.len = p - hdr->name.s;
260                 *p = '\0';
261                 return (p + 1);
262         }
263
264              /* Unknown header type */
265  other:    
266         p = q_memchr(p, ':', end - p);
267         if (!p) {        /* No double colon found, error.. */
268                 hdr->type = HDR_ERROR;
269                 hdr->name.s = 0;
270                 hdr->name.len = 0;
271                 return 0;
272         } else {
273                 hdr->type = HDR_OTHER;
274                 *p = '\0';
275                 hdr->name.len = p - hdr->name.s;
276                 return (p + 1);
277         }
278 }
279
280
281 /* Number of distinct keys */
282 #define NUM_KEYS  608
283
284 /* Number of distinct values */
285 #define NUM_VALS 50
286
287
288 /*
289  * Create synonym-less (precalculated) hash table
290  */
291 void init_hfname_parser(void)
292 {
293         int i, j, k;
294
295              /* Hash table values */
296         unsigned int init_val[NUM_VALS] = {
297                 _Allo_, _Auth_, _oriz_, _atio_, _Call_, __ID2_, __ID1_, _Cont_,
298                 _act2_, _act1_, _ent__, _Leng_, _th12_, _Type_, _CSeq_, _Expi_,
299                 _res2_, _res1_, _From_, _Max__, _Forw_, _ards_, _Prox_, _y_Au_,
300                 _thor_, _izat_, _ion2_, _ion1_, _y_Re_, _quir_, _Reco_, _rd_R_,
301                 _oute_, _Requ_, _ire2_, _ire1_, _Rout_, _Supp_, _orte_, _To12_,
302                 _Unsu_, _ppor_, _ted2_, _ted1_, _Via2_, _Via1_, _WWW__, _enti_,
303                 _cate_, _Even_
304         };
305
306              /* Number of keys associated to each value */
307         unsigned int key_nums[NUM_VALS] = {
308                 16, 16, 16, 16, 16,  4,  4, 16, 
309                  8,  8,  8, 16,  4, 16, 16, 16, 
310                  8,  8, 16,  8, 16, 16, 16,  8, 
311                 16, 16,  8,  8,  8, 16, 16,  8, 
312                 16, 16,  8,  8, 16, 16, 16,  4, 
313                 16, 16,  8,  8,  8,  8,  8, 16,
314                 16, 16
315         };
316
317              /* Hash table keys */
318         unsigned int init_key[NUM_KEYS] = {
319                 _allo_, _allO_, _alLo_, _alLO_, _aLlo_, _aLlO_, _aLLo_, _aLLO_, 
320                 _Allo_, _AllO_, _AlLo_, _AlLO_, _ALlo_, _ALlO_, _ALLo_, _ALLO_, 
321                 _auth_, _autH_, _auTh_, _auTH_, _aUth_, _aUtH_, _aUTh_, _aUTH_, 
322                 _Auth_, _AutH_, _AuTh_, _AuTH_, _AUth_, _AUtH_, _AUTh_, _AUTH_, 
323                 _oriz_, _oriZ_, _orIz_, _orIZ_, _oRiz_, _oRiZ_, _oRIz_, _oRIZ_, 
324                 _Oriz_, _OriZ_, _OrIz_, _OrIZ_, _ORiz_, _ORiZ_, _ORIz_, _ORIZ_, 
325                 _atio_, _atiO_, _atIo_, _atIO_, _aTio_, _aTiO_, _aTIo_, _aTIO_, 
326                 _Atio_, _AtiO_, _AtIo_, _AtIO_, _ATio_, _ATiO_, _ATIo_, _ATIO_, 
327                 _call_, _calL_, _caLl_, _caLL_, _cAll_, _cAlL_, _cALl_, _cALL_, 
328                 _Call_, _CalL_, _CaLl_, _CaLL_, _CAll_, _CAlL_, _CALl_, _CALL_, 
329                 __id2_, __iD2_, __Id2_, __ID2_, __id1_, __iD1_, __Id1_, __ID1_, 
330                 _cont_, _conT_, _coNt_, _coNT_, _cOnt_, _cOnT_, _cONt_, _cONT_, 
331                 _Cont_, _ConT_, _CoNt_, _CoNT_, _COnt_, _COnT_, _CONt_, _CONT_, 
332                 _act2_, _acT2_, _aCt2_, _aCT2_, _Act2_, _AcT2_, _ACt2_, _ACT2_, 
333                 _act1_, _acT1_, _aCt1_, _aCT1_, _Act1_, _AcT1_, _ACt1_, _ACT1_, 
334                 _ent__, _enT__, _eNt__, _eNT__, _Ent__, _EnT__, _ENt__, _ENT__, 
335                 _leng_, _lenG_, _leNg_, _leNG_, _lEng_, _lEnG_, _lENg_, _lENG_, 
336                 _Leng_, _LenG_, _LeNg_, _LeNG_, _LEng_, _LEnG_, _LENg_, _LENG_, 
337                 _th12_, _tH12_, _Th12_, _TH12_, _type_, _typE_, _tyPe_, _tyPE_, 
338                 _tYpe_, _tYpE_, _tYPe_, _tYPE_, _Type_, _TypE_, _TyPe_, _TyPE_, 
339                 _TYpe_, _TYpE_, _TYPe_, _TYPE_, _cseq_, _cseQ_, _csEq_, _csEQ_, 
340                 _cSeq_, _cSeQ_, _cSEq_, _cSEQ_, _Cseq_, _CseQ_, _CsEq_, _CsEQ_, 
341                 _CSeq_, _CSeQ_, _CSEq_, _CSEQ_, _expi_, _expI_, _exPi_, _exPI_, 
342                 _eXpi_, _eXpI_, _eXPi_, _eXPI_, _Expi_, _ExpI_, _ExPi_, _ExPI_, 
343                 _EXpi_, _EXpI_, _EXPi_, _EXPI_, _res2_, _reS2_, _rEs2_, _rES2_, 
344                 _Res2_, _ReS2_, _REs2_, _RES2_, _res1_, _reS1_, _rEs1_, _rES1_, 
345                 _Res1_, _ReS1_, _REs1_, _RES1_, _from_, _froM_, _frOm_, _frOM_, 
346                 _fRom_, _fRoM_, _fROm_, _fROM_, _From_, _FroM_, _FrOm_, _FrOM_, 
347                 _FRom_, _FRoM_, _FROm_, _FROM_, _max__, _maX__, _mAx__, _mAX__, 
348                 _Max__, _MaX__, _MAx__, _MAX__, _forw_, _forW_, _foRw_, _foRW_, 
349                 _fOrw_, _fOrW_, _fORw_, _fORW_, _Forw_, _ForW_, _FoRw_, _FoRW_, 
350                 _FOrw_, _FOrW_, _FORw_, _FORW_, _ards_, _ardS_, _arDs_, _arDS_, 
351                 _aRds_, _aRdS_, _aRDs_, _aRDS_, _Ards_, _ArdS_, _ArDs_, _ArDS_, 
352                 _ARds_, _ARdS_, _ARDs_, _ARDS_, _prox_, _proX_, _prOx_, _prOX_, 
353                 _pRox_, _pRoX_, _pROx_, _pROX_, _Prox_, _ProX_, _PrOx_, _PrOX_, 
354                 _PRox_, _PRoX_, _PROx_, _PROX_, _y_au_, _y_aU_, _y_Au_, _y_AU_, 
355                 _Y_au_, _Y_aU_, _Y_Au_, _Y_AU_, _thor_, _thoR_, _thOr_, _thOR_, 
356                 _tHor_, _tHoR_, _tHOr_, _tHOR_, _Thor_, _ThoR_, _ThOr_, _ThOR_, 
357                 _THor_, _THoR_, _THOr_, _THOR_, _izat_, _izaT_, _izAt_, _izAT_, 
358                 _iZat_, _iZaT_, _iZAt_, _iZAT_, _Izat_, _IzaT_, _IzAt_, _IzAT_, 
359                 _IZat_, _IZaT_, _IZAt_, _IZAT_, _ion2_, _ioN2_, _iOn2_, _iON2_, 
360                 _Ion2_, _IoN2_, _IOn2_, _ION2_, _ion1_, _ioN1_, _iOn1_, _iON1_, 
361                 _Ion1_, _IoN1_, _IOn1_, _ION1_, _y_re_, _y_rE_, _y_Re_, _y_RE_, 
362                 _Y_re_, _Y_rE_, _Y_Re_, _Y_RE_, _quir_, _quiR_, _quIr_, _quIR_, 
363                 _qUir_, _qUiR_, _qUIr_, _qUIR_, _Quir_, _QuiR_, _QuIr_, _QuIR_, 
364                 _QUir_, _QUiR_, _QUIr_, _QUIR_, _reco_, _recO_, _reCo_, _reCO_, 
365                 _rEco_, _rEcO_, _rECo_, _rECO_, _Reco_, _RecO_, _ReCo_, _ReCO_, 
366                 _REco_, _REcO_, _RECo_, _RECO_, _rd_r_, _rd_R_, _rD_r_, _rD_R_, 
367                 _Rd_r_, _Rd_R_, _RD_r_, _RD_R_, _oute_, _outE_, _ouTe_, _ouTE_, 
368                 _oUte_, _oUtE_, _oUTe_, _oUTE_, _Oute_, _OutE_, _OuTe_, _OuTE_, 
369                 _OUte_, _OUtE_, _OUTe_, _OUTE_, _requ_, _reqU_, _reQu_, _reQU_, 
370                 _rEqu_, _rEqU_, _rEQu_, _rEQU_, _Requ_, _ReqU_, _ReQu_, _ReQU_, 
371                 _REqu_, _REqU_, _REQu_, _REQU_, _ire2_, _irE2_, _iRe2_, _iRE2_, 
372                 _Ire2_, _IrE2_, _IRe2_, _IRE2_, _ire1_, _irE1_, _iRe1_, _iRE1_, 
373                 _Ire1_, _IrE1_, _IRe1_, _IRE1_, _rout_, _rouT_, _roUt_, _roUT_, 
374                 _rOut_, _rOuT_, _rOUt_, _rOUT_, _Rout_, _RouT_, _RoUt_, _RoUT_, 
375                 _ROut_, _ROuT_, _ROUt_, _ROUT_, _supp_, _supP_, _suPp_, _suPP_, 
376                 _sUpp_, _sUpP_, _sUPp_, _sUPP_, _Supp_, _SupP_, _SuPp_, _SuPP_, 
377                 _SUpp_, _SUpP_, _SUPp_, _SUPP_, _orte_, _ortE_, _orTe_, _orTE_, 
378                 _oRte_, _oRtE_, _oRTe_, _oRTE_, _Orte_, _OrtE_, _OrTe_, _OrTE_, 
379                 _ORte_, _ORtE_, _ORTe_, _ORTE_, _to12_, _tO12_, _To12_, _TO12_, 
380                 _unsu_, _unsU_, _unSu_, _unSU_, _uNsu_, _uNsU_, _uNSu_, _uNSU_, 
381                 _Unsu_, _UnsU_, _UnSu_, _UnSU_, _UNsu_, _UNsU_, _UNSu_, _UNSU_, 
382                 _ppor_, _ppoR_, _ppOr_, _ppOR_, _pPor_, _pPoR_, _pPOr_, _pPOR_, 
383                 _Ppor_, _PpoR_, _PpOr_, _PpOR_, _PPor_, _PPoR_, _PPOr_, _PPOR_, 
384                 _ted2_, _teD2_, _tEd2_, _tED2_, _Ted2_, _TeD2_, _TEd2_, _TED2_, 
385                 _ted1_, _teD1_, _tEd1_, _tED1_, _Ted1_, _TeD1_, _TEd1_, _TED1_, 
386                 _via2_, _viA2_, _vIa2_, _vIA2_, _Via2_, _ViA2_, _VIa2_, _VIA2_, 
387                 _via1_, _viA1_, _vIa1_, _vIA1_, _Via1_, _ViA1_, _VIa1_, _VIA1_, 
388                 _www__, _wwW__, _wWw__, _wWW__, _Www__, _WwW__, _WWw__, _WWW__, 
389                 _enti_, _entI_, _enTi_, _enTI_, _eNti_, _eNtI_, _eNTi_, _eNTI_, 
390                 _Enti_, _EntI_, _EnTi_, _EnTI_, _ENti_, _ENtI_, _ENTi_, _ENTI_, 
391                 _cate_, _catE_, _caTe_, _caTE_, _cAte_, _cAtE_, _cATe_, _cATE_, 
392                 _Cate_, _CatE_, _CaTe_, _CaTE_, _CAte_, _CAtE_, _CATe_, _CATE_,
393                 _even_, _eveN_, _evEn_, _evEN_, _eVen_, _eVeN_, _eVEn_, _eVEN_, 
394                 _Even_, _EveN_, _EvEn_, _EvEN_, _EVen_, _EVeN_, _EVEn_, _EVEN_, 
395         }; 
396
397              /* Mark all elements as empty */
398         for(i = 0; i < HASH_TABLE_SIZE; i++) {
399                 set_entry(HASH_EMPTY, HASH_EMPTY);
400         }
401
402         k = 0;
403
404         for(i = 0; i < NUM_VALS; i++) {
405                 for(j = 0; j < key_nums[i]; j++) {
406                         set_entry(init_key[k++], init_val[i]);
407                 }
408         }
409 }