📄 mn_ipay.c
字号:
inet_ntoa(from.sin_addr), ntohs(from.sin_port)); if (len < sizeof(IPAY_TYPE)) { DEBUG(DEBUG_IPAY, "\ttoo short message - ignoring it\n"); return; } type = (IPAY_TYPE *) msg; DEBUG(DEBUG_IPAY, "\ttype=%i\n", ntohl(*type)); switch (ntohl(*type)) { case IPAY_MSG_INITIALIZE: handle_initialize(s, msg, len); break; case IPAY_MSG_POLICY_REPLY: handle_policy_prio_reply(s, msg, len); break; case IPAY_MSG_PURCHASE: handle_purchase(s, msg, len); break; case IPAY_MSG_ALLOWANCE: handle_allowance(s, msg, len); break; case IPAY_MSG_PLEASE_PAY_MORE: handle_please_pay_more(s, msg, len); break; case IPAY_MSG_MICRO_PAYMENT: handle_micro_payment(s, msg, len); break; default: DEBUG(DEBUG_IPAY, "\tunknown message type - ignoring " "message\n"); break; }}/* maximum wait time for 'blocking' prio req call in usecs */#define IPAY_MAX_WAIT_TIME 1500000/* policy request retry time in seconds */#define IPAY_RETRY_TIME 120struct prio_cache_data { struct node node; __u32 timePrice; __u32 bytePrice; __u32 priority; time_t req_time; int reply_ok; /* whether a reply was received or not; if not, retry * after IPAY_RETRY_TYIME seconds */};#define PRIO_CACHE_SIZE 19static struct hashtable *prio_cache = NULL;static intprio_hash(void *key, const int hashsize){ int res; struct prio_cache_data *data = (struct prio_cache_data *) key; res = (data->timePrice + data->bytePrice) % PRIO_CACHE_SIZE; return (unsigned) res;}static intprio_cmp(void *key, struct node *cmprd){ struct prio_cache_data *prio1, *prio2; prio1 = (struct prio_cache_data *) key; prio2 = (struct prio_cache_data *) cmprd; if (prio1->timePrice == prio2->timePrice && prio1->bytePrice == prio2->bytePrice) return 1; return 0;}static voidwait_for_reply(void){ fd_set set; struct timeval tv, start, now; int diff; /* wait for the reply for a limited time and also process any other * Ipay messages */ gettimeofday(&start, NULL); diff = 0; for (;;) { tv.tv_sec = (IPAY_MAX_WAIT_TIME - diff) / 1000000; tv.tv_usec = (IPAY_MAX_WAIT_TIME - diff) % 1000000; DEBUG(DEBUG_IPAY, "\twaiting for Ipay reply - timeout %i sec " "%i usec\n", tv.tv_sec, tv.tv_usec); FD_ZERO(&set); FD_SET(mn.ipay_sock, &set); select(mn.ipay_sock + 1, &set, NULL, NULL, &tv); if (FD_ISSET(mn.ipay_sock, &set)) handle_ipay(mn.ipay_sock); if (prio_avail) return; gettimeofday(&now, NULL); diff = (now.tv_sec - start.tv_sec) * 1000000 + now.tv_usec - start.tv_usec; if (diff < 0) { DEBUG(DEBUG_IPAY, "Clock changed?\n"); return; } if (diff >= IPAY_MAX_WAIT_TIME) { DEBUG(DEBUG_IPAY, "Timeout while waiting a reply from " "Ipay buyer\n"); return; } }}__u32 ipay_get_priority(__u32 timePrice, __u32 bytePrice){ struct prio_cache_data *entry = NULL, key; struct ipay_policy_prio_req req; int update_entry = 0; if (!mn.ipay_in_use) return 1; if (prio_cache != NULL) { memset(&key, 0, sizeof(key)); key.timePrice = timePrice; key.bytePrice = bytePrice; if (prio_cache == NULL) { DEBUG(DEBUG_IPAY, "prio_cache == NULL\n"); entry = NULL; } else { entry = (struct prio_cache_data *) hashtable_fetch(prio_cache, prio_hash, &key, prio_cmp); } if (entry != NULL && (entry->reply_ok || time(NULL) < entry->req_time + IPAY_RETRY_TIME)) { DEBUG(DEBUG_IPAY, "ipay_get_priority - prio=%u " "(from cache)\n", entry->priority); return entry->priority; } update_entry = 1; } else { prio_cache = hashtable_init(PRIO_CACHE_SIZE); if (prio_cache == NULL) { DEBUG(DEBUG_IPAY, "Priority cache initialization " "failed\n"); return 1; } } /* ask policy priority from Ipay Buyer */ prio_avail = 0; memset(&req, 0, sizeof(req)); req.type = htonl(IPAY_MSG_POLICY_REQ); req.timePrice = htonl(timePrice); req.bytePrice = htonl(bytePrice); if (send_to_buyer(&req, sizeof(req)) < 0) return 1; wait_for_reply(); /* save the result */ if (!update_entry || entry == NULL) { entry = (struct prio_cache_data *) malloc(sizeof(struct prio_cache_data)); if (entry == NULL) { DEBUG(DEBUG_IPAY, "ipay_get_priority - malloc failed\n"); return 1; } } memset(entry, 0, sizeof(struct prio_cache_data)); entry->timePrice = timePrice; entry->bytePrice = bytePrice; time(&entry->req_time); if (!prio_avail) { DEBUG(DEBUG_IPAY, "No priority reply received in time - " "assuming priority 1\n"); entry->priority = 1; } else { entry->priority = last_prio; entry->reply_ok = 1; } if (!update_entry) { list_init_node(&entry->node); hashtable_add(prio_cache, prio_hash, &entry, &entry->node); } return entry->priority;}static int remove_prio(struct node *node, void *data){ hashtable_remove(node); return 1;}void ipay_flush_priority_cache(int free_mem){ if (prio_cache == NULL) return; hashtable_iterator(prio_cache, remove_prio, NULL); if (free_mem) { hashtable_destroy(prio_cache); prio_cache = NULL; }}void ipay_new_fa(struct agentadv_data *adv){ struct ipay_new_fa new; int len, i; struct fa_nai_ext *nai; unsigned char *c; if (adv->adv.own_ext == NULL) return; if (strncmp(adv->fa_nai, prev_faIdentifier, IPAY_CHAR_LEN) == 0) { DEBUG(DEBUG_IPAY, "ipay_new_fa - using same FA - no report\n"); return; } nai = (struct fa_nai_ext *) adv->fa_nai; DEBUG(DEBUG_IPAY, "ipay_new_fa - reporting FA["); c = MSG_NAI_DATA(nai); for (i = 0; i < GET_NAI_LEN(nai); i++) { if (*c < 32 || *c > 126) DEBUG(DEBUG_IPAY, "<%i>", *c); else DEBUG(DEBUG_IPAY, "%c", *c); c++; } DEBUG(DEBUG_IPAY, "], timePrice=%i, bytePrice=%i\n", ntohl(adv->adv.own_ext->timePrice), ntohl(adv->adv.own_ext->bytePrice)); memset(&new, 0, sizeof(new)); new.type = htonl(IPAY_MSG_NEW_FA); len = GET_NAI_LEN(nai); if (len > IPAY_CHAR_LEN) { DEBUG(DEBUG_IPAY, "\ttoo long FA NAI\n"); len = IPAY_CHAR_LEN; } memcpy(new.faIdentifier, MSG_NAI_DATA(nai), len); new.timePrice = adv->adv.own_ext->timePrice; new.bytePrice = adv->adv.own_ext->bytePrice; send_to_buyer(&new, sizeof(new));}static int ipay_set_priority(struct node *node, void *data){ __u32 prio; struct agentadv_data *adv = (struct agentadv_data *) node; if (adv->adv.own_ext == NULL || (ntohs(adv->ext->opts) & AGENT_ADV_FOREIGN_AGENT) == 0) return 1; DEBUG(DEBUG_IPAY, "ipay_get_priority: time=%i byte=%i\n", ntohl(adv->adv.own_ext->timePrice), ntohl(adv->adv.own_ext->bytePrice)); prio = ipay_get_priority(ntohl(adv->adv.own_ext->timePrice), ntohl(adv->adv.own_ext->bytePrice)); if (prio == 0 && adv->priority > 0) { DEBUG(DEBUG_IPAY, "ipay_set_priority - marking FA unusable " "(prio: %i ==> 0)\n", adv->priority); } /* FIX: adjust edata->adv->priority somehow according to Ipay prio */ return 1;}static int ipay_handle_get_fa(void *data){ struct event_FA *edata = (struct event_FA *) data; hashtable_iterator(edata->hash, ipay_set_priority, NULL); return 0;}static int ipay_handle_iface(void *data){ /* quick hack to make sure that Ipay handler is after monitor handler. * Handler priorities would be a nicer solution.. */ handler_unregister(FA_GET, ipay_handle_get_fa); handler_register(FA_GET, ipay_handle_get_fa); return 0;}void ipay_init(void){ handler_register(FA_GET, ipay_handle_get_fa); handler_register(INTERFACE_INIT, ipay_handle_iface);}void ipay_cleanup(void){ handler_unregister(FA_GET, ipay_handle_get_fa); handler_unregister(INTERFACE_INIT, ipay_handle_iface);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -