Committer: Miika Komu <miika@xxxxxx> Date: 17/03/2010 at 18:22:14 Revision: 3989 Revision-id: miika@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Branch nick: trunk Log: Added missing doxygen for hiprelay.c and moved doxygen from header to source file. Modified: D hipd/hiprelay.c.doxyme M hipd/hiprelay.c M hipd/hiprelay.h === modified file 'hipd/hiprelay.c' --- hipd/hiprelay.c 2010-03-10 17:44:36 +0000 +++ hipd/hiprelay.c 2010-03-17 16:22:12 +0000 @@ -1,8 +1,67 @@ /** @file + * + * Distributed under <a href="http://www.gnu.org/licenses/gpl2.txt";>GNU/GPL</a> + * * This file defines the rendezvous extension and the UDP relay for HIP packets * for the Host Identity Protocol (HIP). See header file for usage - * instructions. Version 1.1 added support for white list and configuration - * file. + * instructions. Supports access control in the form in white lists in + * the /etc/hip/relay_config file. + * + * The HIP relay combines the functionalites of an rendezvous server (RVS) and + * a HIP UDP relay. The HIP relay consists of a hashtable for storing IP address + * to HIT mappings and of functions that do the actual relaying action. The + * hashtable is based on lhash library and its functionalites are the same + * except that the HIP relay stores data (allocated memory for relay records) + * instead of pointers. + * + * A few simple rules apply: + * <ul> + * <li>Allocate memory for relay records that are to be put into the hashtable + * only with hip_relrec_alloc().</li> + * <li>Once a relay record is <b>successfully</b> put into the hashtable, the + * only way delete it is to call hip_relht_rec_free(). This will remove the + * entry from the hashtable and free the memory allocated for the relay record. + * </li> + * </ul> + * + * Usage: + * <ul> + * <li>Inserting a new relay record: + * <pre> + * hip_relrec_t rr = hip_relrec_alloc(...); + * hip_relht_put(rr); + * if(hip_relht_get(rr) == NULL) // The put was unsuccessful. + * { + * if(rr != NULL) + * free(rr); + * } + * </pre> + * </li> + * <li>Fetching a relay record. We do not need (but can use) a fully populated + * relay record as a search key. A dummy record with hit_r field populated + * is sufficient. Note that there is no need to re-put the relay record into the + * hashtable once it has been succesfully inserted into the hashtable - except + * if we change the hit_r field of the relay record. If a relay record with same + * HIT is put into the hashtable, the existing element is deleted. + * + * <pre> + * hip_relrec_t dummy, *fetch_record = NULL; + * memcpy((char *)&(dummy.hit_r), hit, sizeof(hit)); + * fetch_record = hip_relht_get(&dummy); + * if(fetch_record != NULL) + * { + * // Do something with the record. + * } + * </pre> + * </li> + * <li>Deleting a relay record. A dummy record can be used: + * <pre> + * hip_relrec_t dummy; + * memcpy((char *)&(dummy.hit_r), hit, sizeof(hit)); + * hip_relht_rec_free(&dummy); + * </pre> + * </li> + * </ul> * * @author Lauri Silvennoinen * @note Related RFC: <a href="http://www.rfc-editor.org/rfc/rfc5204.txt";> @@ -11,7 +70,8 @@ * <a href="http://www.ietf.org/internet-drafts/draft-ietf-hip-nat-traversal-03.txt";> * draft-ietf-hip-nat-traversal-03</a> * @note Distributed under <a href="http://www.gnu.org/licenses/gpl2.txt";>GNU/GPL</a>. - * @see hiprelay.h + * @note Related RFC: <a href="http://www.rfc-editor.org/rfc/rfc5204.txt";> + * Host Identity Protocol (HIP) Rendezvous Extension</a> */ /* required for s6_addr32 */ @@ -87,125 +147,25 @@ */ hip_relay_wl_status_t whitelist_enabled = HIP_RELAY_WL_ON; -/** - * Initializes the global HIP relay hashtable. Allocates memory for - * @c hiprelay_ht. - * - * @return zero on success, -1 otherwise. - * @note do not call this function directly, instead call hip_relay_init(). - */ +/* forward declarations */ static int hip_relht_init(void); - -/** - * Uninitializes the HIP relay record hashtable @c hiprelay_ht. Frees the memory - * allocated for the hashtable and for the relay records. Thus, after calling - * this function, all memory allocated from the heap related to the relay record - * hashtable is free. - * - * @note do not call this function directly, instead call hip_relay_uninit(). - */ static void hip_relht_uninit(void); - -/** - * Deletes a single entry from the relay record hashtable and frees the memory - * allocated for the record, if the record has expired. The relay record is - * deleted if it has been last contacted more than @c hiprelay_lifetime seconds - * ago. If the parameter relay record is the same record that is being deleted - * (i.e. is located in the same memory location) then the parameter @c rec - * itself is freed. If a dummy record is used (i.e. is located in a different - * memory location thatn the hashtable entry), then @c rec is left untouched. - * - * @param rec a pointer to a relay record. - */ static void hip_relht_rec_free_expired_doall(hip_relrec_t *rec); - -/** - * Initializes the global HIP relay whitelist. Allocates memory for - * @c hiprelay_wl. - * - * @return zero on success, -1 otherwise. - * @note do not call this function directly, instead call hip_relay_init(). - */ static int hip_relwl_init(void); - -/** - * Uninitializes the HIP relay whitelist hashtable @c hiprelay_wl. Frees the - * memory allocated for the hashtable and for the HITs. Thus, after calling - * this function, all memory allocated from the heap related to the whitelist - * is free. - * - * @note do not call this function directly, instead call hip_relay_uninit(). - */ static void hip_relwl_uninit(void); - - -/** - * Puts a HIT into the whitelist. Puts the HIT pointed by @c hit into the - * whitelist hashtable @c hiprelay_wl. If there already is an entry with the - * same HIT, the old value is replaced, and <b>the memory allocated for the - * existing element is freed</b>. Note that we store pointers here, the data are - * not copied. - * - * @param hit a pointer to a HIT to be inserted into the whitelist. - * @return -1 if there was a hash collision i.e. a duplicate HIT is inserted, - * zero otherwise. - * @note <b style="color: #f00;">Do not put HITs allocated from the stack - * into the whitelist.</b> Instead put only HITs created with - * malloc(). - * @note In case of a hash collision, the existing HIT is freed. If you - * store references to HITs that are in the whitelist elsewhere - * outside the whitelist, NULL pointers can result. - */ static int hip_relwl_put(hip_hit_t *hit); - -/** - * Deletes a single entry from the whitelist hashtable and frees the memory - * allocated for the element. The parameter HIT is itself left untouched, it is - * only used as an search key. - * - * @param hit a pointer to a HIT. - */ static void hip_relwl_hit_free_doall(hip_hit_t *hit); - -/** - * Reads RVS / HIP Relay configuration from a file. Reads configuration - * information from @c HIP_RELAY_CONFIG_FILE. - * - * @return zero on success, -ENOENT if the file could not be opened for reading. - * @note The white list @c hiprelay_wl must be initialized before this - * function is called. - */ static int hip_relay_read_config(void); - -/** - * Writes RVS / HIP Relay configuration file with default content. Writes a RVS - * / HIP Relay configuration file to @c HIP_RELAY_CONFIG_FILE. The file is - * opened with "w" argument mode, which means that a possibly existing file is - * truncated to zero length. - * - * @return zero on success, -ENOENT if the file could not be opened for writing. - * @note Truncates existing file to zero length. - */ static int hip_relay_write_config(void); - -/** - * The hash function of the @c hiprelay_ht hashtable. Calculates a hash from - * parameter relay record HIT. - * - * @param rec a pointer to a relay record. - * @return the calculated hash or zero if @c rec or hit_r is NULL. - */ static unsigned long hip_relht_hash(const hip_relrec_t *rec); - -/** - * The hash function of the @c hiprelay_wl hashtable. Calculates a hash from - * parameter HIT. - * - * @param hit a pointer to a HIT. - * @return the calculated hash or zero if @c hit is NULL. - */ static unsigned long hip_relwl_hash(const hip_hit_t *hit); - +static int hip_relay_forward_response(const hip_common_t *r, + const uint8_t type_hdr, + const in6_addr_t *r_saddr, + const in6_addr_t *r_daddr, + const hip_portpair_t *r_info, + const in6_addr_t *relay_to_addr, + const in_port_t relay_to_port); /** * Returns a hash calculated over a HIT. * @@ -243,15 +203,19 @@ return hash; } -static int hip_relay_forward_response(const hip_common_t *r, - const uint8_t type_hdr, - const in6_addr_t *r_saddr, - const in6_addr_t *r_daddr, - const hip_portpair_t *r_info, - const in6_addr_t *relay_to_addr, - const in_port_t relay_to_port); - - +/** + * Deletes a single entry from the relay record hashtable and frees the memory + * allocated for the element if the matching element's type is of @c type. The + * deletion is based on the hash calculated from the relay fecord + * @c hit_r field, and therefore the parameter record does not need to be fully + * populated. If the parameter relay record is the same record that is being + * deleted (i.e. is located in the same memory location) then the parameter + * @c rec itself is freed. If a dummy record is used (i.e. is located in a + * different memory location thatn the hashtable entry), then @c rec is left + * untouched. + * + * @param rec a pointer to a relay record. + */ static void hip_relht_rec_free_type_doall_arg(hip_relrec_t *rec, const hip_relrec_type_t *type) { hip_relrec_t *fetch_record = hip_relht_get(rec); @@ -264,16 +228,34 @@ /** A callback wrapper of the prototype required by @c lh_doall_arg(). */ static IMPLEMENT_LHASH_DOALL_ARG_FN(hip_relht_rec_free_type, hip_relrec_t, hip_relrec_type_t) +/** + * Returns relay status. + * + * @return HIP_RELAY_ON if the RVS / relay is "on", HIP_RELAY_OFF otherwise. + */ hip_relay_status_t hip_relay_get_status() { return relay_enabled; } +/** + * Sets the status of the RVS / relay. Sets the relay "on" or "off". + * + * @param status zero if the relay is to be disabled, anything else to enable + * the relay. + */ void hip_relay_set_status(hip_relay_status_t status) { relay_enabled = status; } +/** + * The hash function of the @c hiprelay_ht hashtable. Calculates a hash from + * parameter relay record HIT. + * + * @param rec a pointer to a relay record. + * @return the calculated hash or zero if @c rec or hit_r is NULL. + */ static unsigned long hip_relht_hash(const hip_relrec_t *rec) { if (rec == NULL || &(rec->hit_r) == NULL) { @@ -286,6 +268,13 @@ /** A callback wrapper of the prototype required by @c lh_new(). */ static IMPLEMENT_LHASH_HASH_FN(hip_relht, const hip_relrec_t) +/** + * relay hash table comparison function + * + * @param rec1 a hip_relrec_t structure + * @param rec2 a hip_relrec_t structure + * @return zero if the structures are equal or one otherwise + */ static int hip_relht_cmp(const hip_relrec_t *rec1, const hip_relrec_t *rec2) { if (rec1 == NULL || &(rec1->hit_r) == NULL || @@ -299,6 +288,26 @@ /** A callback wrapper of the prototype required by @c lh_new(). */ static IMPLEMENT_LHASH_COMP_FN(hip_relht, const hip_relrec_t) +/** + * Puts a relay record into the hashtable. Puts the relay record pointed by + * @c rec into the hashtable @c hiprelay_ht. If there already is an entry with + * the same key the old value is replaced, and <b>the memory allocated for the + * existing element is freed</b>. Note that we store pointers here, the data are + * not copied. There should be no need to put a relay record more than once into + * the hashtable. If the fields of an individual relay record need to be + * changed, just retrieve the record with @c hip_relht_get() and alter the + * fields of it, but do not re-put it into the hashtable. + * + * @param rec a pointer to a relay record to be inserted into the hashtable. + * @return -1 if there was a hash collision i.e. an entry with duplicate HIT + * is inserted, zero otherwise. + * @note <b style="color: #f00;">Do not put records allocated from stack + * into the hashtable.</b> Instead put only records created with + * hip_relrec_alloc(). + * @note In case of a hash collision, the existing relay record is freed. + * If you store references to relay records that are in the hashtable + * elsewhere outside the hashtable, NULL pointers can result. + */ int hip_relht_put(hip_relrec_t *rec) { hip_relrec_t key, *match; @@ -324,6 +333,14 @@ } } +/** + * Retrieves a relay record from the hashtable @c hiprelay_ht. The parameter + * record @c rec only needs to have field @c hit_r populated. + * + * @param rec a pointer to a relay record. + * @return a pointer to a fully populated relay record if found, NULL + * otherwise. + */ hip_relrec_t *hip_relht_get(const hip_relrec_t *rec) { if (hiprelay_ht == NULL || rec == NULL) { @@ -333,6 +350,18 @@ return (hip_relrec_t *) list_find(rec, hiprelay_ht); } +/** + * Deletes a single entry from the relay record hashtable and frees the memory + * allocated for the element. The deletion is based on the hash calculated from + * the relay fecord @c hit_r field, and therefore the parameter record does not + * need to be fully populated. If the parameter relay record is the same record + * that is being deleted (i.e. is located in the same memory location) then + * the parameter @c rec itself is freed. If a dummy record is used (i.e. is + * located in a different memory location thatn the hashtable entry), then + * @c rec is left untouched. + * + * @param rec a pointer to a relay record. + */ void hip_relht_rec_free_doall(hip_relrec_t *rec) { if (hiprelay_ht == NULL || rec == NULL) { @@ -355,6 +384,17 @@ /** A callback wrapper of the prototype required by @c lh_doall(). */ static IMPLEMENT_LHASH_DOALL_FN(hip_relht_rec_free, hip_relrec_t) +/** + * Deletes a single entry from the relay record hashtable and frees the memory + * allocated for the record, if the record has expired. The relay record is + * deleted if it has been last contacted more than @c hiprelay_lifetime seconds + * ago. If the parameter relay record is the same record that is being deleted + * (i.e. is located in the same memory location) then the parameter @c rec + * itself is freed. If a dummy record is used (i.e. is located in a different + * memory location thatn the hashtable entry), then @c rec is left untouched. + * + * @param rec a pointer to a relay record. + */ static void hip_relht_rec_free_expired_doall(hip_relrec_t *rec) { if (rec == NULL) { // No need to check hiprelay_ht @@ -370,6 +410,11 @@ /** A callback wrapper of the prototype required by @c lh_doall(). */ static IMPLEMENT_LHASH_DOALL_FN(hip_relht_rec_free_expired, hip_relrec_t) +/** + * Returns the number of relay records in the hashtable @c hiprelay_ht. + * + * @return number of relay records in the hashtable. + */ unsigned long hip_relht_size() { if (hiprelay_ht == NULL) { @@ -379,6 +424,14 @@ return ((struct lhash_st *) hiprelay_ht)->num_items; } +/** + * Periodic maintenance function of the hip relay. This function should be + * called once in every maintenance cycle of the hip daemon. It clears the + * expired relay records by calling @c hip_relht_rec_free_expired() for every + * element in the hashtable. + * @todo a REG_RESPONSE with zero lifetime should be sent to each client whose + * registration is cancelled. + */ void hip_relht_maintenance() { if (hiprelay_ht == NULL) { @@ -391,6 +444,12 @@ ((struct lhash_st *) hiprelay_ht)->down_load = tmp; } +/** + * Deletes all entries of @c type from the relay record hashtable and frees the + * memory allocated for the deleted elements. + * + * @param type the type of the records to be deleted. + */ void hip_relht_free_all_of_type(const hip_relrec_type_t type) { if (hiprelay_ht == NULL) { @@ -404,6 +463,21 @@ ((struct lhash_st *) hiprelay_ht)->down_load = tmp; } +/** + * Allocates a new relay record. + * + * @param type the type of this relay record (HIP_FULLRELAY or + * HIP_RVSRELAY). + * @param lifetime the lifetime of this relayrecord as defined in registration + * draft. + * @param hit_r a pointer to Responder (relay client) HIT. + * @param ip_r a pointer to Responder (relay client) IP address. + * @param port responder's UDP port. + * @return a pointer to a new relay record, or NULL if failed to + * allocate. + * @note All records to be put in the hashtable should be created with + * this function. + */ hip_relrec_t *hip_relrec_alloc(const hip_relrec_type_t type, const uint8_t lifetime, const in6_addr_t *hit_r, const hip_hit_t *ip_r, @@ -433,6 +507,19 @@ return rec; } +/** + * Sets the mode of a relay record. This function sets the @c flags field of a + * relay record. + * + * @param rec a pointer to a relay record. + * @param mode the mode to be set for the parameter record. One of the following: + * <ul> + * <li>HIP_REL_NONE</li> + * <li>HIP_REL_UDP</li> + * <li>HIP_REL_TCP</li> + * </ul> + * @see hip_relrec_t for a bitmap. + */ void hip_relrec_set_mode(hip_relrec_t *rec, const hip_relrec_type_t type) { if (rec != NULL) { @@ -440,6 +527,13 @@ } } +/** + * Sets the lifetime of a relay record. + * The service lifetime is set to 2^((lifetime - 64)/8) seconds. + * + * @param rec a pointer to a relay record. + * @param lifetime the lifetime of the above formula. + */ void hip_relrec_set_lifetime(hip_relrec_t *rec, const uint8_t lifetime) { if (rec != NULL) { @@ -447,6 +541,12 @@ } } +/** + * Sets the UDP port number of a relay record. + * + * @param rec a pointer to a relay record. + * @param port UDP port number. + */ void hip_relrec_set_udpport(hip_relrec_t *rec, const in_port_t port) { if (rec != NULL) { @@ -454,6 +554,11 @@ } } +/** + * Prints info of the parameter relay record using @c HIP_INFO() macro. + * + * @param rec a pointer to a relay record. + */ void hip_relrec_info(const hip_relrec_t *rec) { if (rec == NULL) { @@ -499,6 +604,13 @@ HIP_DEBUG("\n%s", status); } +/** + * The hash function of the @c hiprelay_wl hashtable. Calculates a hash from + * parameter HIT. + * + * @param hit a pointer to a HIT. + * @return the calculated hash or zero if @c hit is NULL. + */ static unsigned long hip_relwl_hash(const hip_hit_t *hit) { if (hit == NULL) { @@ -511,6 +623,14 @@ /** A callback wrapper of the prototype required by @c lh_new(). */ static IMPLEMENT_LHASH_HASH_FN(hip_relwl, const hip_hit_t) +/** + * The compare function of the @c hiprelay_wl hashtable. Compares the hash + * values calculated from parameter @c hit1 and @c hit2. + * + * @param hit1 a pointer to a HIT. + * @param hit2 a pointer to a HIT. + * @return 0 if keys are equal and neither is NULL, non-zero otherwise. + */ static int hip_relwl_cmp(const hip_hit_t *hit1, const hip_hit_t *hit2) { if (hit1 == NULL || hit2 == NULL) { @@ -523,6 +643,23 @@ /** A callback wrapper of the prototype required by @c lh_new(). */ static IMPLEMENT_LHASH_COMP_FN(hip_relwl, const hip_hit_t) +/** + * Puts a HIT into the whitelist. Puts the HIT pointed by @c hit into the + * whitelist hashtable @c hiprelay_wl. If there already is an entry with the + * same HIT, the old value is replaced, and <b>the memory allocated for the + * existing element is freed</b>. Note that we store pointers here, the data are + * not copied. + * + * @param hit a pointer to a HIT to be inserted into the whitelist. + * @return -1 if there was a hash collision i.e. a duplicate HIT is inserted, + * zero otherwise. + * @note <b style="color: #f00;">Do not put HITs allocated from the stack + * into the whitelist.</b> Instead put only HITs created with + * malloc(). + * @note In case of a hash collision, the existing HIT is freed. If you + * store references to HITs that are in the whitelist elsewhere + * outside the whitelist, NULL pointers can result. + */ static int hip_relwl_put(hip_hit_t *hit) { if (hiprelay_wl == NULL || hit == NULL) { @@ -544,6 +681,12 @@ } } +/** + * Retrieves a HIT from the hashtable @c hiprelay_wl. + * + * @param hit a pointer to a HIT. + * @return a pointer to a matching HIT, NULL otherwise. + */ hip_hit_t *hip_relwl_get(const hip_hit_t *hit) { if (hiprelay_wl == NULL || hit == NULL) { @@ -570,6 +713,13 @@ #endif /* CONFIG_HIP_DEBUG */ +/** + * Deletes a single entry from the whitelist hashtable and frees the memory + * allocated for the element. The parameter HIT is itself left untouched, it is + * only used as an search key. + * + * @param hit a pointer to a HIT. + */ static void hip_relwl_hit_free_doall(hip_hit_t *hit) { if (hiprelay_wl == NULL || hit == NULL) { @@ -592,11 +742,32 @@ /** A callback wrapper of the prototype required by @c lh_doall(). */ static IMPLEMENT_LHASH_DOALL_FN(hip_relwl_hit_free, hip_hit_t) +/** + * Returns the whitelist status. + * + * @return HIP_RELAY_ON if the RVS / relay whitelist is "on", HIP_RELAY_OFF + * otherwise. + */ hip_relay_wl_status_t hip_relwl_get_status() { return whitelist_enabled; } +/** + * Validates a requested RVS service lifetime. If + * @c requested_lifetime is smaller than @c hiprelay_min_lifetime then + * @c granted_lifetime is set to @c hiprelay_min_lifetime. If + * @c requested_lifetime is greater than @c hiprelay_max_lifetime then + * @c granted_lifetime is set to @c hiprelay_max_lifetime. Else + * @c granted_lifetime is set to @c requested_lifetime. + * + * @param requested_lifetime the lifetime that is to be validated. + * @param granted_lifetime a target buffer for the validated lifetime. + * @return -1 if @c requested_lifetime is outside boundaries, + * i.e. is smaller than @c hiprelay_min_lifetime or + * is greater than @c hiprelay_max_lifetime. Zero + * otherwise. + */ int hip_rvs_validate_lifetime(uint8_t requested_lifetime, uint8_t *granted_lifetime) { @@ -612,6 +783,45 @@ } } +#if 0 +/** + * Validates a requested HIP relay service lifetime. If + * @c requested_lifetime is smaller than @c hiprelay_min_lifetime then + * @c granted_lifetime is set to @c hiprelay_min_lifetime. If + * @c requested_lifetime is greater than @c hiprelay_max_lifetime then + * @c granted_lifetime is set to @c hiprelay_max_lifetime. Else + * @c granted_lifetime is set to @c requested_lifetime. + * + * @param requested_lifetime the lifetime that is to be validated. + * @param granted_lifetime a target buffer for the validated lifetime. + * @return -1 if @c requested_lifetime is outside boundaries, + * i.e. is smaller than @c hiprelay_min_lifetime or + * is greater than @c hiprelay_max_lifetime. Zero + * otherwise. + * @note Currently this is just a call back wrapper for + * hip_rvs_validate_lifetime() because RVS and relay + * services share the same lifetimes. + */ +static int hip_relay_validate_lifetime(uint8_t requested_lifetime, + uint8_t *granted_lifetime) +{ + return hip_rvs_validate_lifetime(requested_lifetime, + granted_lifetime); +} +#endif + +/** + * forward a control packet in relay or rvs mode + * + * @param msg the HIP control message to be forwarded + * @param saddr source address of the message + * @param daddr destination address of the message + * @param rec the relay record corresponding to the packet + * @param info transport port number information + * @param type_hdr message type + * @param relay_type rvs vs. relay + * @return zero on success and negative on failure + */ int hip_relay_forward(const hip_common_t *msg, const in6_addr_t *saddr, const in6_addr_t *daddr, hip_relrec_t *rec, const hip_portpair_t *info, const uint8_t type_hdr, @@ -747,6 +957,14 @@ return err; } +/** + * Reads RVS / HIP Relay configuration from a file. Reads configuration + * information from @c HIP_RELAY_CONFIG_FILE. + * + * @return zero on success, -ENOENT if the file could not be opened for reading. + * @note The white list @c hiprelay_wl must be initialized before this + * function is called. + */ static int hip_relay_read_config() { FILE *fp = NULL; @@ -848,6 +1066,15 @@ return err; } +/** + * Writes RVS / HIP Relay configuration file with default content. Writes a RVS + * / HIP Relay configuration file to @c HIP_RELAY_CONFIG_FILE. The file is + * opened with "w" argument mode, which means that a possibly existing file is + * truncated to zero length. + * + * @return zero on success, -ENOENT if the file could not be opened for writing. + * @note Truncates existing file to zero length. + */ static int hip_relay_write_config() { int err = 0; @@ -868,10 +1095,14 @@ } /** - * @todo Xiang! Please, add decent Doxygen comments, check the doxy syntax - * from doc/HACKING. Stick to C-coding style using LINUX indendation. - * No lines over 80 characters. No capital letters in funcion names - * (C-style). Function commmends should be in header file. + * handle a HIP control message with relay_to parameter + * + * @param msg the message with the relay_to parameter + * @param msg_type the type of the message + * @param src_addr the source address of the message + * @param dst_addr the destination address of the message + * @param msg_info transport port numbers + * @return zero on success or negative on error */ int hip_relay_handle_relay_to(struct hip_common *msg, int msg_type, @@ -935,10 +1166,15 @@ } /** - * @todo Xiang! Please, add decent Doxygen comments, check the doxy syntax - * from doc/HACKING. Stick to C-coding style using LINUX indendation. - * No lines over 80 characters. No capital letters in funcion names - * (C-style). Function commmends should be in header file. + * forward a HIP control packet with relay_to parameter + * + * @param r the HIP control message to be relayed + * @param r_saddr the original source address + * @param r_daddr the original destination address + * @param r_info the transport layer ports + * @param relay_to_addr the address where to relay the packet + * @param relay_to_port the port where to relay the packet + * @return zero on success or negative on error */ static int hip_relay_forward_response(const hip_common_t *r, const uint8_t type_hdr, @@ -991,6 +1227,15 @@ return err; } +/** + * store the address of a peer's rendezvous server to the host association + * + * @param source_msg the I1 message + * @param entry the host association + * @return zero on success or negative on error + * + * @todo handle also the relay case + */ int hip_relay_add_rvs_to_ha(hip_common_t *source_msg, hip_ha_t *entry) { struct hip_via_rvs *via_rvs = NULL; @@ -1023,14 +1268,23 @@ } /** - * function return -1 means error - * return 0, means parameter not found - * return 1, means parameter found and verified - * @todo Xiang! Please, add decent Doxygen comments, check the doxy syntax - * from doc/HACKING. Stick to C-coding style using LINUX indendation. - * No lines over 80 characters. No capital letters in funcion names - * (C-style). Function commmends should be in header file. - * + * Handles a FROM/RELAY_FROM parameter. + * + * Checks if the parameter @c source_msg message has a FROM/RELAY_FROM + * parameter. If a parameter is found, the values are copied to target buffers + * @c dest_ip and @c dest_port. Next the hmac in RVS_HMAC is verified using + * the host association created during registration. This host association + * is searched using hitr from @c source_msg and @c rvs_ip as search keys. + * + * @param source_msg a pointer to the I1 HIP packet common header with source + * and destination HITs. + * @param rvs_ip a pointer to the source address from where the I1 packet + * was received. + * @param dest_ip a target buffer for the IP address in the FROM/RELAY_FROM + * parameter. + * @param dest_port a target buffer for the port number in RELAY_FROM + * parameter. + * @return zero */ int hip_relay_handle_from(hip_common_t *source_msg, in6_addr_t *rvs_ip, @@ -1102,13 +1356,12 @@ } /** - * function return -1 means error - * return 0, means parameter not found - * return 1, means parameter found and verified - * @todo Xiang! Please, add decent Doxygen comments, check the doxy syntax - * from doc/HACKING. Stick to C-coding style using LINUX indendation. - * No lines over 80 characters. No capital letters in funcion names - * (C-style). Function commmends should be in header file. + * handle relay_from parameter in a HIP control message + * + * @param source_msg the HIP control message + * @param relay_ip the source IP address of the message + * @param dest_ip the relayed destination will be written here + * @param dest_port the relayed destination port will be written here */ int hip_relay_handle_relay_from(hip_common_t *source_msg, in6_addr_t *relay_ip, @@ -1187,6 +1440,17 @@ return 1; } +/** + * handle the relay_to parameter at the Initiator + * + * @param msg the HIP control packet with relay_to parameter + * @param msg_type the type of the HIP control message + * @param src_addr source address of the message + * @param dst_addr destination address of the message + * @param msg_info transport layer port information + * @param entry the host association + * @return zero on success or negative on error + */ int hip_relay_handle_relay_to_in_client(struct hip_common *msg, int msg_type, struct in6_addr *src_addr, @@ -1238,6 +1502,13 @@ return err; } +/** + * Initializes the global HIP relay hashtable. Allocates memory for + * @c hiprelay_ht. + * + * @return zero on success, -1 otherwise. + * @note do not call this function directly, instead call hip_relay_init(). + */ static int hip_relht_init() { /* Check that the relay hashtable is not already initialized. */ @@ -1255,6 +1526,14 @@ return 0; } +/** + * Uninitializes the HIP relay record hashtable @c hiprelay_ht. Frees the memory + * allocated for the hashtable and for the relay records. Thus, after calling + * this function, all memory allocated from the heap related to the relay record + * hashtable is free. + * + * @note do not call this function directly, instead call hip_relay_uninit(). + */ static void hip_relht_uninit() { if (hiprelay_ht == NULL) { @@ -1266,6 +1545,10 @@ hiprelay_ht = NULL; } +/** + * Initializes the HIP relay / RVS. Initializes the HIP relay hashtable and + * whitelist. + */ int hip_relay_init() { int err = 0; @@ -1299,12 +1582,28 @@ return err; } +/** + * Uninitializes the HIP relay / RVS. Uninitializes the HIP relay hashtable and + * whitelist. + */ void hip_relay_uninit() { hip_relht_uninit(); hip_relwl_uninit(); } +/** + * Reinitializes the HIP relay / RVS. Deletes the old values from the relay + * whitelist and reads new values from the configuration file + * @c HIP_RELAY_CONFIG_FILE. Besides the whitelist values also every other + * value read from the configuration file is reinitialized. These include the + * lifetime values etc. However, the existing relay records are left as they + * were. This means that the relay / RVS clients that have already registered + * continue to be served as before - even if their HIT nomore exists in the + * whitelist. + * + * @return zero if the configuration file was read succesfully, -1 otherwise. + */ int hip_relay_reinit() { int err = 0; @@ -1319,6 +1618,13 @@ return err; } +/** + * Initializes the global HIP relay whitelist. Allocates memory for + * @c hiprelay_wl. + * + * @return zero on success, -1 otherwise. + * @note do not call this function directly, instead call hip_relay_init(). + */ static int hip_relwl_init() { /* Check that the relay whitelist is not already initialized. */ @@ -1336,6 +1642,14 @@ return 0; } +/** + * Uninitializes the HIP relay whitelist hashtable @c hiprelay_wl. Frees the + * memory allocated for the hashtable and for the HITs. Thus, after calling + * this function, all memory allocated from the heap related to the whitelist + * is free. + * + * @note do not call this function directly, instead call hip_relay_uninit(). + */ static void hip_relwl_uninit() { if (hiprelay_wl == NULL) { === modified file 'hipd/hiprelay.h' --- hipd/hiprelay.h 2010-03-10 17:44:36 +0000 +++ hipd/hiprelay.h 2010-03-17 16:22:12 +0000 @@ -1,71 +1,13 @@ /** @file + * + * Distributed under <a href="http://www.gnu.org/licenses/gpl2.txt";>GNU/GPL</a>. + * * A header file for hiprelay.c. * - * The HIP relay combines the functionalites of an rendezvous server (RVS) and - * a HIP UDP relay. The HIP relay consists of a hashtable for storing IP address - * to HIT mappings and of functions that do the actual relaying action. The - * hashtable is based on lhash library and its functionalites are the same - * except that the HIP relay stores data (allocated memory for relay records) - * instead of pointers. - * - * A few simple rules apply: - * <ul> - * <li>Allocate memory for relay records that are to be put into the hashtable - * only with hip_relrec_alloc().</li> - * <li>Once a relay record is <b>successfully</b> put into the hashtable, the - * only way delete it is to call hip_relht_rec_free(). This will remove the - * entry from the hashtable and free the memory allocated for the relay record. - * </li> - * </ul> - * - * Usage: - * <ul> - * <li>Inserting a new relay record: - * <pre> - * hip_relrec_t rr = hip_relrec_alloc(...); - * hip_relht_put(rr); - * if(hip_relht_get(rr) == NULL) // The put was unsuccessful. - * { - * if(rr != NULL) - * free(rr); - * } - * </pre> - * </li> - * <li>Fetching a relay record. We do not need (but can use) a fully populated - * relay record as a search key. A dummy record with hit_r field populated - * is sufficient. Note that there is no need to re-put the relay record into the - * hashtable once it has been succesfully inserted into the hashtable - except - * if we change the hit_r field of the relay record. If a relay record with same - * HIT is put into the hashtable, the existing element is deleted. - * - * <pre> - * hip_relrec_t dummy, *fetch_record = NULL; - * memcpy((char *)&(dummy.hit_r), hit, sizeof(hit)); - * fetch_record = hip_relht_get(&dummy); - * if(fetch_record != NULL) - * { - * // Do something with the record. - * } - * </pre> - * </li> - * <li>Deleting a relay record. A dummy record can be used: - * <pre> - * hip_relrec_t dummy; - * memcpy((char *)&(dummy.hit_r), hit, sizeof(hit)); - * hip_relht_rec_free(&dummy); - * </pre> - * </li> - * </ul> - * * @author Lauri Silvennoinen - * @version 1.1 - * @date 31.03.2008 - * @note Related RFC: <a href="http://www.rfc-editor.org/rfc/rfc5204.txt";> - * Host Identity Protocol (HIP) Rendezvous Extension</a> * @note Related draft: * <a href="http://www.ietf.org/internet-drafts/draft-ietf-hip-nat-traversal-03.txt";> * draft-ietf-hip-nat-traversal-03</a> - * @note Distributed under <a href="http://www.gnu.org/licenses/gpl2.txt";>GNU/GPL</a>. */ #ifndef HIP_HIPD_HIPRELAY_H #define HIP_HIPD_HIPRELAY_H @@ -133,366 +75,54 @@ /** Possible states of the whitelist. */ typedef enum { HIP_RELAY_WL_OFF = 0, HIP_RELAY_WL_ON = 1 } hip_relay_wl_status_t; -/** - * Returns relay status. - * - * @return HIP_RELAY_ON if the RVS / relay is "on", HIP_RELAY_OFF otherwise. - */ hip_relay_status_t hip_relay_get_status(void); - -/** - * Sets the status of the RVS / relay. Sets the relay "on" or "off". - * - * @param status zero if the relay is to be disabled, anything else to enable - * the relay. - */ void hip_relay_set_status(hip_relay_status_t status); - -/** - * Initializes the HIP relay / RVS. Initializes the HIP relay hashtable and - * whitelist. - */ int hip_relay_init(void); - -/** - * Uninitializes the HIP relay / RVS. Uninitializes the HIP relay hashtable and - * whitelist. - */ void hip_relay_uninit(void); - -/** - * Reinitializes the HIP relay / RVS. Deletes the old values from the relay - * whitelist and reads new values from the configuration file - * @c HIP_RELAY_CONFIG_FILE. Besides the whitelist values also every other - * value read from the configuration file is reinitialized. These include the - * lifetime values etc. However, the existing relay records are left as they - * were. This means that the relay / RVS clients that have already registered - * continue to be served as before - even if their HIT nomore exists in the - * whitelist. - * - * @return zero if the configuration file was read succesfully, -1 otherwise. - */ int hip_relay_reinit(void); - -/** - * Sets the mode of a relay record. This function sets the @c flags field of a - * relay record. - * - * @param rec a pointer to a relay record. - * @param mode the mode to be set for the parameter record. One of the following: - * <ul> - * <li>HIP_REL_NONE</li> - * <li>HIP_REL_UDP</li> - * <li>HIP_REL_TCP</li> - * </ul> - * @see hip_relrec_t for a bitmap. - */ void hip_relrec_set_mode(hip_relrec_t *rec, const hip_relrec_type_t type); - -/** - * Sets the lifetime of a relay record. - * The service lifetime is set to 2^((lifetime - 64)/8) seconds. - * - * @param rec a pointer to a relay record. - * @param lifetime the lifetime of the above formula. - */ void hip_relrec_set_lifetime(hip_relrec_t *rec, const uint8_t lifetime); - -/** - * Sets the UDP port number of a relay record. - * - * @param rec a pointer to a relay record. - * @param port UDP port number. - */ void hip_relrec_set_udpport(hip_relrec_t *rec, const in_port_t port); - -/** - * Prints info of the parameter relay record using @c HIP_INFO() macro. - * - * @param rec a pointer to a relay record. - */ void hip_relrec_info(const hip_relrec_t *rec); - -/** - * The compare function of the @c hiprelay_ht hashtable. Compares the hash - * values calculated from parameters @c rec1 and @c rec2. - * - * @param rec1 a pointer to a HIT. - * @param rec2 a pointer to a HIT. - * @return 0 if keys are equal and neither is NULL, non-zero otherwise. - */ -int hip_relht_compare(const hip_relrec_t *rec1, const hip_relrec_t *rec2); - -/** - * Puts a relay record into the hashtable. Puts the relay record pointed by - * @c rec into the hashtable @c hiprelay_ht. If there already is an entry with - * the same key the old value is replaced, and <b>the memory allocated for the - * existing element is freed</b>. Note that we store pointers here, the data are - * not copied. There should be no need to put a relay record more than once into - * the hashtable. If the fields of an individual relay record need to be - * changed, just retrieve the record with @c hip_relht_get() and alter the - * fields of it, but do not re-put it into the hashtable. - * - * @param rec a pointer to a relay record to be inserted into the hashtable. - * @return -1 if there was a hash collision i.e. an entry with duplicate HIT - * is inserted, zero otherwise. - * @note <b style="color: #f00;">Do not put records allocated from stack - * into the hashtable.</b> Instead put only records created with - * hip_relrec_alloc(). - * @note In case of a hash collision, the existing relay record is freed. - * If you store references to relay records that are in the hashtable - * elsewhere outside the hashtable, NULL pointers can result. - */ int hip_relht_put(hip_relrec_t *rec); - -/** - * Retrieves a relay record from the hashtable @c hiprelay_ht. The parameter - * record @c rec only needs to have field @c hit_r populated. - * - * @param rec a pointer to a relay record. - * @return a pointer to a fully populated relay record if found, NULL - * otherwise. - */ hip_relrec_t *hip_relht_get(const hip_relrec_t *rec); - -/** - * Deletes a single entry from the relay record hashtable and frees the memory - * allocated for the element. The deletion is based on the hash calculated from - * the relay fecord @c hit_r field, and therefore the parameter record does not - * need to be fully populated. If the parameter relay record is the same record - * that is being deleted (i.e. is located in the same memory location) then - * the parameter @c rec itself is freed. If a dummy record is used (i.e. is - * located in a different memory location thatn the hashtable entry), then - * @c rec is left untouched. - * - * @param rec a pointer to a relay record. - */ void hip_relht_rec_free_doall(hip_relrec_t *rec); - -/** - * Deletes a single entry from the relay record hashtable and frees the memory - * allocated for the element if the matching element's type is of @c type. The - * deletion is based on the hash calculated from the relay fecord - * @c hit_r field, and therefore the parameter record does not need to be fully - * populated. If the parameter relay record is the same record that is being - * deleted (i.e. is located in the same memory location) then the parameter - * @c rec itself is freed. If a dummy record is used (i.e. is located in a - * different memory location thatn the hashtable entry), then @c rec is left - * untouched. - * - * @param rec a pointer to a relay record. - */ void hip_relht_rec_free_type_doall(hip_relrec_t *rec, const hip_relrec_type_t *type); - -/** - * Returns the number of relay records in the hashtable @c hiprelay_ht. - * - * @return number of relay records in the hashtable. - */ unsigned long hip_relht_size(void); - -/** - * Periodic maintenance function of the hip relay. This function should be - * called once in every maintenance cycle of the hip daemon. It clears the - * expired relay records by calling @c hip_relht_rec_free_expired() for every - * element in the hashtable. - * @todo a REG_RESPONSE with zero lifetime should be sent to each client whose - * registration is cancelled. - */ void hip_relht_maintenance(void); - -/** - * Allocates a new relay record. - * - * @param type the type of this relay record (HIP_FULLRELAY or - * HIP_RVSRELAY). - * @param lifetime the lifetime of this relayrecord as defined in registration - * draft. - * @param hit_r a pointer to Responder (relay client) HIT. - * @param ip_r a pointer to Responder (relay client) IP address. - * @param port responder's UDP port. - * @return a pointer to a new relay record, or NULL if failed to - * allocate. - * @note All records to be put in the hashtable should be created with - * this function. - */ hip_relrec_t *hip_relrec_alloc(const hip_relrec_type_t type, const uint8_t lifetime, const in6_addr_t *hit_r, const hip_hit_t *ip_r, const in_port_t port, const hip_crypto_key_t *hmac, const hip_xmit_func_t func); - -/** - * Deletes all entries of @c type from the relay record hashtable and frees the - * memory allocated for the deleted elements. - * - * @param type the type of the records to be deleted. - */ void hip_relht_free_all_of_type(const hip_relrec_type_t type); - -/** - * The compare function of the @c hiprelay_wl hashtable. Compares the hash - * values calculated from parameter @c hit1 and @c hit2. - * - * @param hit1 a pointer to a HIT. - * @param hit2 a pointer to a HIT. - * @return 0 if keys are equal and neither is NULL, non-zero otherwise. - */ int hip_relwl_compare(const hip_hit_t *hit1, const hip_hit_t *hit2); - -/** - * Retrieves a HIT from the hashtable @c hiprelay_wl. - * - * @param hit a pointer to a HIT. - * @return a pointer to a matching HIT, NULL otherwise. - */ hip_hit_t *hip_relwl_get(const hip_hit_t *hit); - -/** - * Returns the whitelist status. - * - * @return HIP_RELAY_ON if the RVS / relay whitelist is "on", HIP_RELAY_OFF - * otherwise. - */ hip_relay_wl_status_t hip_relwl_get_status(void); - -/** - * Validates a requested RVS service lifetime. If - * @c requested_lifetime is smaller than @c hiprelay_min_lifetime then - * @c granted_lifetime is set to @c hiprelay_min_lifetime. If - * @c requested_lifetime is greater than @c hiprelay_max_lifetime then - * @c granted_lifetime is set to @c hiprelay_max_lifetime. Else - * @c granted_lifetime is set to @c requested_lifetime. - * - * @param requested_lifetime the lifetime that is to be validated. - * @param granted_lifetime a target buffer for the validated lifetime. - * @return -1 if @c requested_lifetime is outside boundaries, - * i.e. is smaller than @c hiprelay_min_lifetime or - * is greater than @c hiprelay_max_lifetime. Zero - * otherwise. - */ int hip_rvs_validate_lifetime(uint8_t requested_lifetime, uint8_t *granted_lifetime); - int hip_relay_forward(const hip_common_t *msg, const in6_addr_t *saddr, const in6_addr_t *daddr, hip_relrec_t *rec, const hip_portpair_t *info, const uint8_t type_hdr, const hip_relrec_type_t relay_type); - -/** - * Validates a requested HIP relay service lifetime. If - * @c requested_lifetime is smaller than @c hiprelay_min_lifetime then - * @c granted_lifetime is set to @c hiprelay_min_lifetime. If - * @c requested_lifetime is greater than @c hiprelay_max_lifetime then - * @c granted_lifetime is set to @c hiprelay_max_lifetime. Else - * @c granted_lifetime is set to @c requested_lifetime. - * - * @param requested_lifetime the lifetime that is to be validated. - * @param granted_lifetime a target buffer for the validated lifetime. - * @return -1 if @c requested_lifetime is outside boundaries, - * i.e. is smaller than @c hiprelay_min_lifetime or - * is greater than @c hiprelay_max_lifetime. Zero - * otherwise. - * @note Currently this is just a call back wrapper for - * hip_rvs_validate_lifetime() because RVS and relay - * services share the same lifetimes. - */ -static inline int hip_relay_validate_lifetime(uint8_t requested_lifetime, - uint8_t *granted_lifetime) -{ - return hip_rvs_validate_lifetime(requested_lifetime, - granted_lifetime); -} - -/** - * Relays an incoming I1 packet. - * - * This function relays an incoming I1 packet to the next node on path - * to receiver and inserts a @c FROM parameter encapsulating the source IP - * address. In case there is a NAT between the sender (the initiator or previous - * RVS) of the I1 packet, a @c RELAY_FROM parameter is inserted instead of a - * @c FROM parameter. Next node on path is typically the responder, but if the - * message is to travel multiple rendezvous servers en route to responder, next - * node can also be another rendezvous server. In this case the @c FROM - * (@c RELAY_FROM) parameter is appended after the existing ones. Thus current RVS - * appends the address of previous RVS and the final RVS (n) in the RVS chain - * sends @c FROM:I, @c FROM:RVS1, ... , <code>FROM:RVS(n-1)</code>. If initiator - * is located behind a NAT, the first @c FROM parameter is replaced with a - * @c RELAY_FROM parameter. - * - * @param i1 a pointer to the I1 HIP packet common header with source and - * destination HITs. - * @param i1_saddr a pointer to the source address from where the I1 packet was - * received. - * @param i1_daddr a pointer to the destination address where the I1 packet was - * sent to (own address). - * @param rec a pointer to a relay record matching the HIT of Responder. - * @param i1_info a pointer to the source and destination ports (when NAT is - * in use). - * @return zero on success, or negative error value on error. - * @note This code has not been tested thoroughly with multiple RVSes. - * @note This function is a copy-paste from the previous RVS - * implementation - */ -int hip_relay_rvs(const hip_common_t *i1, - const in6_addr_t *i1_saddr, - const in6_addr_t *i1_daddr, hip_relrec_t *rec, - const hip_portpair_t *i1_info); - int hip_relay_add_rvs_to_ha(hip_common_t *source_msg, hip_ha_t *entry); - - -/** - * Handles a FROM/RELAY_FROM parameter. - * - * Checks if the parameter @c source_msg message has a FROM/RELAY_FROM - * parameter. If a parameter is found, the values are copied to target buffers - * @c dest_ip and @c dest_port. Next the hmac in RVS_HMAC is verified using - * the host association created during registration. This host association - * is searched using hitr from @c source_msg and @c rvs_ip as search keys. - * - * @param source_msg a pointer to the I1 HIP packet common header with source - * and destination HITs. - * @param rvs_ip a pointer to the source address from where the I1 packet - * was received. - * @param dest_ip a target buffer for the IP address in the FROM/RELAY_FROM - * parameter. - * @param dest_port a target buffer for the port number in RELAY_FROM - * parameter. - * @return zero - */ - int hip_relay_handle_from(hip_common_t *source_msg, in6_addr_t *rvs_ip, in6_addr_t *dest_ip, in_port_t *dest_port); - int hip_relay_handle_relay_from(hip_common_t *source_msg, in6_addr_t *relay_ip, in6_addr_t *dest_ip, in_port_t *dest_port); - int hip_relay_handle_relay_to_in_client(struct hip_common *msg, int msg_type, struct in6_addr *src_addr, struct in6_addr *dst_addr, hip_portpair_t *msg_info, hip_ha_t *entry); - - int hip_relay_handle_relay_to(struct hip_common *msg, int msg_type, struct in6_addr *src_addr, struct in6_addr *dst_addr, hip_portpair_t *msg_info); -/** - * function for full relay service. from I to R - * - */ -int hip_relay_forward_I(const hip_common_t *i1, - const in6_addr_t *i1_saddr, - const in6_addr_t *i1_daddr, hip_relrec_t *rec, - const hip_portpair_t *i1_info, - const uint8_t); - #endif /* HIP_HIPD_HIPRELAY_H */