wtp_tid.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:6k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * wtp_tid.c - Implementation of WTP tid validation tests. Note that only 
  3.  * WTP responder uses tid validation.
  4.  *
  5.  * By Aarno Syv鋘en for Wapit Ltd.
  6.  */
  7. #include "gwlib/gwlib.h"
  8. #include "wtp_tid.h"
  9. /*
  10.  * Constants used for defining the tid cache status
  11.  */
  12. enum {
  13.     no_cache = -1,
  14.     iniatilised = -2,
  15.     not_iniatilised = -3,
  16.     cached = 0
  17. };
  18. /*
  19.  * Global data structure:
  20.  *
  21.  * Tid cache is implemented by using a library object List
  22.  */
  23.  static List *tid_cache = NULL;   
  24. /*****************************************************************************
  25.  * Prototypes of internal functions
  26.  */
  27. static WTPCached_tid *cache_item_create_empty(void);
  28. static void cache_item_destroy(void *item);
  29. /*
  30. static void cache_item_dump(WTPCached_tid *item);
  31. */
  32. static void add_tid(WTPRespMachine *resp_machine, long tid);
  33. static void set_tid_by_item(WTPCached_tid *item, long tid);
  34. static int tid_in_window(long rcv_tid, long last_tid);
  35. static WTPCached_tid *tid_cached(WTPRespMachine *resp_machine);
  36. /******************************************************************************
  37.  *
  38.  * External functions:
  39.  */
  40. void wtp_tid_cache_init(void) 
  41. {
  42.     tid_cache = list_create();
  43. }
  44. void wtp_tid_cache_shutdown(void) 
  45. {
  46.     debug("wap.wtp_tid", 0, "%ld items left in the tid cache", 
  47.           list_len(tid_cache));
  48.     list_destroy(tid_cache, cache_item_destroy);
  49. }
  50. /*
  51.  * Tid verification is invoked, when tid_new flag of the incoming message is 
  52.  * on. It is not, if the initiator is not yet cached. If initiator is cached, 
  53.  * the received tid is stored.
  54.  */
  55. int wtp_tid_is_valid(WAPEvent *event, WTPRespMachine *resp_machine)
  56. {
  57.     long rcv_tid = -1,
  58.          last_tid = -1;
  59.     WTPCached_tid *item = NULL;
  60. #if 0
  61.     debug("wap.wtp.tid", 0, "starting validation");
  62. #endif
  63.     rcv_tid = resp_machine->tid;
  64.    
  65.     if (!event->u.RcvInvoke.tid_new) {
  66. /*
  67.  * First we check whether the current initiator has a cache item for it.
  68.  */      
  69.         if ((item = tid_cached(resp_machine)) == NULL) {
  70.             if (event->u.RcvInvoke.no_cache_supported)
  71.                 return no_cached_tid;
  72.             else {
  73. #if 0
  74.              debug("wap.wtp.tid", 0, "empty cache");    
  75. #endif
  76.         add_tid(resp_machine, rcv_tid);
  77.                 return ok;
  78.             }
  79.         }
  80. /*
  81.  * If it has, we check if the message is a duplicate or has tid wrapped up 
  82.  * confusingly.
  83.  */      
  84.         last_tid = item->tid; 
  85.       
  86.         if (tid_in_window(rcv_tid, last_tid) == 0){
  87.             info(0, "WTP_TID: tid out of the window");
  88.             return fail;
  89.         } else {
  90. #if 0
  91.             debug("wap.wtp.tid", 0, "tid in the window");
  92. #endif
  93.             set_tid_by_item(item, rcv_tid);
  94.             return ok;
  95.         }
  96.     } else {
  97.         info(0, "WTP_TID: tid_new flag on");
  98.         rcv_tid = 0;
  99.         if (item == NULL) {
  100.             add_tid(resp_machine, rcv_tid);
  101.         } else {
  102.             set_tid_by_item(item, rcv_tid);
  103.         }
  104.      
  105.         return fail;
  106.    }
  107. /*
  108.  * This return is unnecessary but the compiler demands it
  109.  */
  110.    return fail;
  111. }
  112. /*
  113.  * Changes tid value used by an existing initiator. Input responder machine 
  114.  * and the new tid.
  115.  */
  116. void wtp_tid_set_by_machine(WTPRespMachine *resp_machine, long tid)
  117. {
  118.     WTPCached_tid *item = NULL;
  119.        
  120.     item = tid_cached(resp_machine);
  121.     set_tid_by_item(item, tid);
  122. }
  123. /*****************************************************************************
  124.  *
  125.  * Internal functions:
  126.  *
  127.  * Checks whether the received tid is inside the window of acceptable ones. 
  128.  * The size of the window is set by the constant WTP_TID_WINDOW_SIZE (half of 
  129.  * the tid space is the recommended value). 
  130.  *
  131.  * Inputs: stored tid, received tid. Output 0, if received tid is outside the 
  132.  * window, 1, if it is inside.
  133.  */
  134. static int tid_in_window(long rcv_tid, long last_tid)
  135. {
  136. #if 0
  137.     debug("wap.wtp.tid", 0, "tids were rcv_tid, %ld and last_tid, %ld"
  138.           " and test window %ld", rcv_tid, last_tid, WTP_TID_WINDOW_SIZE); 
  139. #endif
  140.     if (last_tid == rcv_tid) {
  141. return 0;
  142.     } 
  143.     if (rcv_tid > last_tid) {
  144. if (abs(rcv_tid - last_tid) <= WTP_TID_WINDOW_SIZE) {
  145.             return 1;
  146.         } else {
  147.             return 0;
  148.         }
  149.     }
  150.        
  151.     if (rcv_tid < last_tid) {
  152.         if (abs(rcv_tid - last_tid) >= WTP_TID_WINDOW_SIZE){
  153.             return 1;
  154.         } else {
  155.            return 0;
  156.         }
  157.     }
  158. /*
  159.  * Following return is unnecessary but our compiler demands it
  160.  */
  161.        return 0;
  162. }
  163. static WTPCached_tid *cache_item_create_empty(void)
  164. {
  165.     WTPCached_tid *item = NULL;
  166.     item = gw_malloc(sizeof(*item));
  167.     item->addr_tuple = NULL;
  168.     item->tid = 0;
  169.     return item;
  170. }
  171. static void cache_item_destroy(void *p)
  172. {
  173.     WTPCached_tid *item;
  174.     item = p;
  175.     wap_addr_tuple_destroy(item->addr_tuple);
  176.     gw_free(item);
  177. }
  178. /*
  179.  * Checking whether there is an item stored for a specific initiator. Receives 
  180.  * address quadruplet - the identifier it uses - from object WTPRespMachine. 
  181.  * Ditto tid. Returns the item or NULL, if there is not one. Initiator is 
  182.  * identified by the address four-tuple.
  183.  */
  184. static int tid_is_cached(void *a, void *b)
  185. {
  186.     WAPAddrTuple *initiator_profile;
  187.     WTPCached_tid *item;
  188.     item = a;
  189.     initiator_profile = b;
  190.     return wap_addr_tuple_same(item->addr_tuple, initiator_profile);
  191. }
  192. static WTPCached_tid *tid_cached(WTPRespMachine *resp_machine)
  193. {
  194.     WTPCached_tid *item = NULL;
  195.     item = list_search(tid_cache, resp_machine->addr_tuple, tid_is_cached);
  196.     return item;
  197. }
  198. /*
  199.  * Adds an item to the tid cache, one item per every initiator. Initiator is 
  200.  * identified by the address four-tuple, fetched from a wtp responder machine.
  201.  */ 
  202. static void add_tid(WTPRespMachine *resp_machine, long tid)
  203. {
  204.     WTPCached_tid *new_item = NULL;
  205.        
  206.     new_item = cache_item_create_empty(); 
  207.     new_item->addr_tuple = wap_addr_tuple_duplicate(resp_machine->addr_tuple);
  208.     new_item->tid = tid; 
  209.     list_append(tid_cache, new_item);
  210. }
  211. /*
  212.  * Set tid for an existing initiator. Input a cache item and the new tid.
  213.  */
  214. static void set_tid_by_item(WTPCached_tid *item, long tid)
  215. {
  216.     list_lock(tid_cache);
  217.     item->tid = tid;
  218.     list_unlock(tid_cache);
  219. }