rendered paste bodydiff --git src/message.c src/message.cindex 1892a33..3dea0d2 100644--- src/message.c+++ src/message.c@@ -1306,8 +1306,33 @@ guint32 message_ike_auth_i_payload_next(struct session *session, guint32 curr) #ifdef MOBIKE case (N_MOBIKE_SUPPORTED << 8 | IKEV2_PAYLOAD_NOTIFY):- next = IKEV2_PAYLOAD_SA;++ if(session->local_ipv4_addresses_ptr)+ next = (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY);+ else if(session->local_ipv6_addresses_ptr)+ next = (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY);+ else+ next = IKEV2_PAYLOAD_SA; break;++ case (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY):++ if(session->local_ipv4_addresses_ptr->next)+ next = (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY);+ else if(session->local_ipv6_addresses_ptr)+ next = (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY);+ else+ next = IKEV2_PAYLOAD_SA;+ break;++ case (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY):++ if(session->local_ipv6_addresses_ptr->next)+ next = (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY);+ else+ next = IKEV2_PAYLOAD_SA;+ break;+ #endif /* MOBIKE */ case IKEV2_PAYLOAD_SA:@@ -1360,9 +1385,26 @@ int message_send_ike_auth_i(struct session *session) guint32 enclen, ilen, payloadid_len = 0; GSList *certs_for_peer; GSList *sig_ca_items = NULL, *hash_ca_items = NULL;+#ifdef MOBIKE+ /*+ * IPv4 and IPv6 address buffers+ */+ unsigned long addr;+ char addr6[16];++ struct network_address *addr_data;++ GSList *lcl4ptr, *lcl6ptr;+#endif /* MOBIKE */ LOG_FUNC_START(1); +#ifdef MOBIKE+ session->ike_auth_exchange_counter++;++ session->local_ipv4_addresses_ptr = session->local_ipv4_addresses;+ session->local_ipv6_addresses_ptr = session->local_ipv6_addresses;+#endif /* MOBIKE */ retval = -1; buffer = NULL; @@ -1597,6 +1639,33 @@ int message_send_ike_auth_i(struct session *session) LOG_DEBUG("Created MOBIKE_SUPPORTED notification"); LOG_TRACE("Created NOTIFY payload len = %u", len); break;++ case (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY):+ lcl4ptr = session->local_ipv4_addresses_ptr;+ addr_data = (struct network_address *)(lcl4ptr->data);+ addr = 0;+ addr_data->netaddr;+ /*->sin.sin_addr.s_addr;*/++ len = payload_notify_mobike_create(next, N_ADDITIONAL_IP4_ADDRESS,+ (char *)addr, (guint16)(htons(sizeof(addr))), p);+ LOG_DEBUG("Created ADDITIONAL_IP4_ADDRESS notification");+ LOG_TRACE("Created NOTIFY payload len = %u", len);+ session->local_ipv4_addresses_ptr =+ session->local_ipv4_addresses_ptr->next;+ break;++ case (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY):+ addr6 =+ session->local_ipv6_addresses_ptr->data->netaddr->sin6.sin6_addr.s6_addr;++ len = payload_notify_mobike_create(next, N_ADDITIONAL_IP6_ADDRESS,+ addr6, (guint16)(htons(sizeof(addr6))), p);+ LOG_DEBUG("Created ADDITIONAL_IP6_ADDRESS notification");+ LOG_TRACE("Created NOTIFY payload len = %u", len);+ session->local_ipv6_addresses_ptr =+ session->local_ipv6_addresses_ptr->next;+ break; #endif /* MOBIKE */ } @@ -1770,8 +1839,33 @@ guint32 message_ike_auth_r_payload_next(struct session *session, guint32 curr) #ifdef MOBIKE case (N_MOBIKE_SUPPORTED << 8 | IKEV2_PAYLOAD_NOTIFY):- next = IKEV2_PAYLOAD_SA;++ if(session->local_ipv4_addresses_ptr)+ next = (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY);+ else if(session->local_ipv6_addresses_ptr)+ next = (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY);+ else+ next = IKEV2_PAYLOAD_SA; break;++ case (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY):++ if(session->local_ipv4_addresses_ptr->next)+ next = (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY);+ else if(session->local_ipv6_addresses_ptr)+ next = (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY);+ else+ next = IKEV2_PAYLOAD_SA;+ break;++ case (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY):++ if(session->local_ipv6_addresses_ptr->next)+ next = (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY);+ else+ next = IKEV2_PAYLOAD_SA;+ break;+ #endif /* MOBIKE */ case IKEV2_PAYLOAD_SA:@@ -1826,9 +1920,23 @@ int message_send_ike_auth_r(struct session *session, gpointer payloadid = NULL; int auth_payload_len, payloadid_len = 0; GSList *certs_for_peer;+#ifdef MOBIKE+ /*+ * IPv4 and IPv6 address buffers+ */+ unsigned long addr;+ char addr6[16];++ struct network_address *addr_data;+#endif /* MOBIKE */ LOG_FUNC_START(1); +#ifdef MOBIKE+ session->local_ipv4_addresses_ptr = session->local_ipv4_addresses;+ session->local_ipv6_addresses_ptr = session->local_ipv6_addresses;+#endif /* MOBIKE */+ /* * Find corresponding CHILD SA structure */@@ -2022,6 +2130,34 @@ int message_send_ike_auth_r(struct session *session, LOG_DEBUG("Created MOBIKE_SUPPORTED notification"); LOG_TRACE("Created NOTIFY payload len = %u", len); break;++ case (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY):+ /* addr_data = (struct netaddr *) */+/* *((struct network_address *)+ g_slist_nth_data(session->local_ipv4_addresses_ptr, 0));+ addr = 0;+ addr_data; */+ /*->sin.sin_addr.s_addr;*/++ len = payload_notify_mobike_create(next, N_ADDITIONAL_IP4_ADDRESS,+ (char *)addr, (guint16)(htons(sizeof(addr))), p);+ LOG_DEBUG("Created ADDITIONAL_IP4_ADDRESS notification");+ LOG_TRACE("Created NOTIFY payload len = %u", len);+ session->local_ipv4_addresses_ptr =+ session->local_ipv4_addresses_ptr->next;+ break;++ case (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY):+/* addr6 =+ session->local_ipv6_addresses_ptr->data->netaddr->sin6.sin6_addr.s6_addr;+*/+ len = payload_notify_mobike_create(next, N_ADDITIONAL_IP6_ADDRESS,+ addr6, (guint16)(htons(sizeof(addr6))), p);+ LOG_DEBUG("Created ADDITIONAL_IP6_ADDRESS notification");+ LOG_TRACE("Created NOTIFY payload len = %u", len);+ session->local_ipv6_addresses_ptr =+ session->local_ipv6_addresses_ptr->next;+ break; #endif /* MOBIKE */ }@@ -4366,9 +4502,27 @@ gint message_parse_ike_auth_i(struct ikev2_header *hdr, gchar *p, guint32 r1, r2; struct cert *cert; struct certreq *certreq;+#ifdef MOBIKE+ gboolean no_additional_addresses = FALSE;+ struct netaddr *peer_addr;+ guint16 mobike_notify_len;+#endif /* MOBIKE */ LOG_FUNC_START(1); +#ifdef MOBIKE+ /*+ * Create peer's address list of only one element at the moment -+ * source address found in header.+ */+ if(netaddr_get_family(msg->srcaddr) == AF_INET)+ msg->ike_auth.peer_ipv4_addresses =+ g_slist_append(NULL, msg->srcaddr);+ else if(netaddr_get_family(msg->srcaddr) == AF_INET6)+ msg->ike_auth.peer_ipv6_addresses =+ g_slist_append(NULL, msg->srcaddr);+#endif /* MOBIKE */+ /* * Assume that error occured... */@@ -4704,7 +4858,7 @@ gint message_parse_ike_auth_i(struct ikev2_header *hdr, gchar *p, } - LOG_DEBUG("Received N_MOBIKE_SUPPORTED notification!");+ LOG_DEBUG("Received MOBIKE_SUPPORTED notification!"); msg->ike_auth.peer_supports_mobike = TRUE; if ((r2 = message_find_next_payload(&p, &ptype, hdr))) {@@ -4715,6 +4869,63 @@ gint message_parse_ike_auth_i(struct ikev2_header *hdr, gchar *p, np = (struct payload_notify *)p; }++ /*+ * Process ADDITIONAL_*_ADDRESS notify payloads+ */+ while(ptype == IKEV2_PAYLOAD_NOTIFY &&+ (ntohs(np->n_type) == N_ADDITIONAL_IP4_ADDRESS ||+ ntohs(np->n_type) == N_ADDITIONAL_IP6_ADDRESS)) {++ if (payload_notify_check(p) < 0) {+ r1 |= MSGPARSE_SEND_NOTIFY;+ msg->notify = N_INVALID_SYNTAX;+ goto out;+ }++ payload_notify_parse(&peer_addr, &mobike_notify_len, p);++ if(ntohs(np->n_type) == N_ADDITIONAL_IP4_ADDRESS) {+ LOG_DEBUG("Received ADDITIONAL_IP4_ADDRESS notification");+ msg->ike_auth.peer_ipv4_addresses = g_slist_prepend(+ msg->ike_auth.peer_ipv4_addresses, peer_addr);+ }+ else {+ LOG_DEBUG("Received ADDITIONAL_IP4_ADDRESS notification");+ msg->ike_auth.peer_ipv6_addresses = g_slist_prepend(+ msg->ike_auth.peer_ipv6_addresses, peer_addr);+ }++ if ((r2 = message_find_next_payload(&p, &ptype, hdr))) {+ r1 |= (r2 & 0xFFFF0000);+ msg->notify = r2 & 0xFFFF;+ goto out;+ }++ np = (struct payload_notify *)p;+ }++ if (ptype == IKEV2_PAYLOAD_NOTIFY &&+ ntohs(np->n_type) == N_NO_ADDITIONAL_ADDRESSES) {++ if (payload_notify_check(p) < 0) {+ r1 |= MSGPARSE_SEND_NOTIFY;+ msg->notify = N_INVALID_SYNTAX;+ goto out;+ }++ no_additional_addresses = TRUE;++ LOG_DEBUG("Received NO_ADDITIONAL_ADDRESSES notification!");++ if ((r2 = message_find_next_payload(&p, &ptype, hdr))) {+ r1 |= (r2 & 0xFFFF0000);+ msg->notify = r2 & 0xFFFF;+ goto out;+ }++ np = (struct payload_notify *)p;+ } #endif /* MOBIKE */ if (ptype == IKEV2_PAYLOAD_SA) {@@ -4807,6 +5018,25 @@ gint message_parse_ike_auth_i(struct ikev2_header *hdr, gchar *p, } /*+ * Check if we received N_NO_ADDITIONAL_ADDRESSES and if so,+ * assert header source address is the only one, hence there was+ * no ADDITIONAL_*_ADDRESS notify payload.+ */+#ifdef MOBIKE+ if(no_additional_addresses == TRUE)+ if((msg->ike_auth.peer_ipv4_addresses &&+ msg->ike_auth.peer_ipv4_addresses->next) ||+ (msg->ike_auth.peer_ipv6_addresses &&+ msg->ike_auth.peer_ipv6_addresses->next)) {+ LOG_ERROR("Received notify payload for additional address as"+ "well as NO_ADDITIONAL_ADDRESSES");+ r1 |= MSGPARSE_SEND_NOTIFY;+ msg->notify = N_INVALID_SYNTAX;+ goto out;+ }+#endif MOBIKE++ /* * No error occured... */ r1 = 0;@@ -4896,9 +5126,27 @@ gint message_parse_ike_auth_r(struct ikev2_header *hdr, gchar *p, guint32 r1, r2; struct cert *cert; gboolean error;+#ifdef MOBIKE+ gboolean no_additional_addresses = FALSE;+ struct netaddr *peer_addr;+ guint16 mobike_notify_len;+#endif /* MOBIKE */ LOG_FUNC_START(1); +#ifdef MOBIKE+ /*+ * Create peer's address list of only one element at the moment -+ * source address found in header.+ */+ if(netaddr_get_family(msg->srcaddr) == AF_INET)+ msg->ike_auth.peer_ipv4_addresses =+ g_slist_append(NULL, msg->srcaddr);+ else if(netaddr_get_family(msg->srcaddr) == AF_INET6)+ msg->ike_auth.peer_ipv6_addresses =+ g_slist_append(NULL, msg->srcaddr);+#endif /* MOBIKE */+ /* * Assume that error occured... */@@ -5126,6 +5374,23 @@ gint message_parse_ike_auth_r(struct ikev2_header *hdr, gchar *p, case N_MOBIKE_SUPPORTED: msg->ike_auth.peer_supports_mobike = TRUE; break;++ case N_ADDITIONAL_IP4_ADDRESS:+ payload_notify_parse(&peer_addr, &mobike_notify_len, p);+ msg->ike_auth.peer_ipv4_addresses = g_slist_prepend(+ msg->ike_auth.peer_ipv4_addresses, peer_addr);+ break;++ case N_ADDITIONAL_IP6_ADDRESS:+ payload_notify_parse(&peer_addr, &mobike_notify_len, p);+ msg->ike_auth.peer_ipv6_addresses = g_slist_prepend(+ msg->ike_auth.peer_ipv6_addresses, peer_addr);+ break;++ case N_NO_ADDITIONAL_ADDRESSES:+ no_additional_addresses = TRUE;+ break;+ #endif /*MOBIKE */ default:@@ -5252,6 +5517,25 @@ out_finish: } /*+ * Check if we received N_NO_ADDITIONAL_ADDRESSES and if so,+ * assert header source address is the only one, hence there was+ * no ADDITIONAL_*_ADDRESS notify payload.+ */+#ifdef MOBIKE+ if(no_additional_addresses == TRUE)+ if((msg->ike_auth.peer_ipv4_addresses &&+ msg->ike_auth.peer_ipv4_addresses->next) ||+ (msg->ike_auth.peer_ipv6_addresses &&+ msg->ike_auth.peer_ipv6_addresses->next)) {+ LOG_ERROR("Received notify payload for additional address as"+ "well as NO_ADDITIONAL_ADDRESSES");+ r1 |= MSGPARSE_SEND_NOTIFY;+ msg->notify = N_INVALID_SYNTAX;+ goto out;+ }+#endif MOBIKE++ /* * No error occured... */ r1 = 0;diff --git src/message_msg.h src/message_msg.hindex 35912bd..b6231a4 100644--- src/message_msg.h+++ src/message_msg.h@@ -133,7 +133,7 @@ struct ike_sa_init { struct ike_auth { /**- * Does initiator requested transport mode?+ * Has initiator requested transport mode? */ gint transport_mode:1; @@ -245,6 +245,14 @@ struct ike_auth { */ GSList *cert_list; GSList *certreq_list;++ /**+ * Lists of remote peer's IPv4 and IPv6 addresses+ */+#ifdef MOBIKE+ GSList *peer_ipv4_addresses;+ GSList *peer_ipv6_addresses;+#endif /* MOBIKE */ }; /**diff --git src/network.c src/network.cindex 342b5de..5069923 100644--- src/network.c+++ src/network.c@@ -1676,3 +1676,182 @@ out: return retval; } +/**+ * Compares two interfaces by name and index.+ *+ * @param ni1 First interface to compare+ * @param ni2 Second interface to compare+ *+ * \return 1 If two interfaces differ by name or index or both+ * 0 Otherwise+ */+int network_compare_interfaces(struct netif *ni1, struct netif *ni2) {++ LOG_FUNC_START(1);++ if(strcmp(netif_get_name(ni1), netif_get_name(ni2)))+ return 1;++ LOG_FUNC_END(1);++ return ni1->if_index == ni2->if_index ? 0 : 1;+}++/**+ * Compares interfaces in two network_data structures.+ *+ * @param data1 First network_data data which interfaces are to be compared+ * @param data2 Second network_data data to be compared to data1 interfaces+ *+ * \return 1 If interfaces in data1 and data2 differ+ * 0 otherwise+ */+int network_compare_interface_lists(struct network_data *data1,+ struct network_data *data2) {++ int retval;+ GSList *list1, *list2;++ LOG_FUNC_START(1);++ retval = 0;++ list1 = data1->interfaces;+ list2 = data2->interfaces;++ /*+ * Iterate through both interface lists one interface at a time+ */+ while(list1 && list2 && !retval) {++ if(network_compare_interfaces(list1->data, list2->data))+ retval = 1;++ list1 = list1->next;+ list2 = list2->next;+ }++ if(list1 || list2)+ retval = 1;++ LOG_FUNC_END(1);++ return retval;+}+++/**+ * Compares addresses in two network_data structures.+ *+ * @param data1 First network_data data which addresses are to be compared+ * @param data2 Second network_data data to be compared to data1 addresses+ *+ * \return 1 If addresses in data1 and data2 differ+ * 0 otherwise+ */+int network_compare_address_lists(struct network_data *data1,+ struct network_data *data2) {++ int retval;+ GSList *list1, *list2;+ struct network_address *a1, *a2;++ LOG_FUNC_START(1);++ retval = 0;++ list1 = data1->addresses;+ list2 = data2->addresses;++ /*+ * Iterate through both address lists one address at a time+ */+ while(list1 && list2 && !retval) {++ a1 = (struct network_addresss *)(list1->data);+ a2 = (struct network_addresss *)(list2->data);++ if(netaddr_same_family(a1->netaddr, a2->netaddr)) {+ if(netaddr_cmp_ip2ip(a1->netaddr, a2->netaddr))+ retval = 1;+ }+ else+ retval = 1;+++ list1 = list1->next;+ list2 = list2->next;+ }++ if(list1 || list2)+ retval = 1;++ LOG_FUNC_END(1);++ return retval;+}++/**+ * Checks for changes in network interfaces and addresses.+ */+void network_check_links() {++ struct network_data *network_data_new;+ gboolean queue_message;++ LOG_FUNC_START(1);++ network_data_new = g_malloc0(sizeof(struct network_data));+ queue_message = FALSE;++ /*+ * TODO: what does context represent?+ */+ network_data_new->context = NULL;++ /*+ * Lock interfaces and addresses in network_data for reading+ */+ g_static_rw_lock_reader_lock(&network_data->interfaces_lock);+ g_static_rw_lock_reader_lock(&network_data->addresses_lock);++ if (network_enumerate_interfaces(network_data_new) < 0)+ goto out;++ /*+ * Search for IPv4 addresses+ */+ if (network_enumerate_addresses(network_data_new, AF_INET) < 0)+ goto out;++ /*+ * Search for IPv6 addresses+ */+ if (network_enumerate_addresses(network_data_new, AF_INET6) < 0)+ goto out;++ /*+ * Compare interfaces and addresses+ */+ if(network_compare_interface_lists(network_data_new, network_data))+ queue_message = TRUE;+ else if(network_compare_address_lists(network_data_new, network_data))+ queue_message = TRUE;++ /*+ * Send message to some queue if interfaces or addresses have changed+ */+ if(queue_message == TRUE) {+ /*+ * Tu treba poslati neku poruku (treba ju oblikovati) u neki red.+ * Netko po primitku te poruke treba izbrisati postojei automat+ * stanja parova IP adresa+ */+ }++out:+ g_static_rw_lock_reader_unlock(&network_data->interfaces_lock);+ g_static_rw_lock_reader_unlock(&network_data->addresses_lock);++ LOG_FUNC_END(1);+}diff --git src/network.h src/network.hindex f928577..9a6d519 100644--- src/network.h+++ src/network.h@@ -181,8 +181,8 @@ struct network_data { * * TODO: This has to be converted into hash indexed by interface name */+ GStaticRWLock interfaces_lock; GSList *interfaces;- }; #else /* __NETWORK_C */diff --git src/payload.c src/payload.cindex 1cd2f20..79e274f 100644--- src/payload.c+++ src/payload.c@@ -1157,6 +1157,10 @@ gint32 payload_notify_parse(void **data, guint16 *notify_data_len, char *p) p += sizeof(struct payload_notify); ntype = ntohs(np->n_type); + /*+ * Be careful about this check because MOBIKE introduces+ * new notify payloads with ntype > 16395+ */ if (ntype == 0 || (ntype > 39 && ntype < 16384) || (ntype > 16395)) {@@ -1227,6 +1231,19 @@ gint32 payload_notify_parse(void **data, guint16 *notify_data_len, char *p) *((guint32 *)(*data)) = *((guint32 *)p); break; +#ifdef MOBIKE+ case N_MOBIKE_SUPPORTED:+ case NO_ADDITIONAL_ADDRESSES:+ break;++ case N_ADDITIONAL_IP4_ADDRESS:+ case N_ADDITIONAL_IP4_ADDRESS:+ *data = p;+ *notify_data_len = ntohs(np->length) -+ sizeof(struct payload_notify);+ break;+#endif /* MOBIKE */+ default: printf ("ERROR: Unknown/unsupported notify (0x%x) in " "%s:%s:%d\n", diff --git src/session.c src/session.cindex 9569983..7c0aae9 100644--- src/session.c+++ src/session.c@@ -123,6 +123,14 @@ struct session *session_new(void) session->embedded_sm_msg = NULL; + session->peer_addresses = NULL;++#ifdef MOBIKE+ ike_auth_exchange_counter = 0;++ session_local_addresses_init(session);+#endif /* MOBIKE */+ LOG_FUNC_END(2); return session;@@ -251,6 +259,7 @@ gboolean session_free(struct session *session) if (session->sent_resp_mux) g_mutex_free(session->sent_resp_mux); + if (session) g_free (session); } else {@@ -1093,3 +1102,47 @@ gboolean session_use_radius(struct session *session) #endif return FALSE; }++#ifdef MOBIKE+GSList *session_add_address(GSList *list,+ struct netaddr *addr) {++ GSList *new_address = NULL;++ LOG_FUNC_START(1);++ new_address = g_slist_prepend(new_address, addr);+ new_address = g_slist_prepend(list, new_address);++ LOG_FUNC_END(1);++ return new_address;+}++void session_local_addresses_init(struct session *session) {++ GSList *network_data_iterator;+ struct network_address *addr;++ LOG_FUNC_START(1);++ network_data_iterator = network_data->addresses;++ session->local_ipv4_addresses = NULL;+ session->local_ipv6_addresses = NULL;++ while(network_data_iterator) {+ addr = (struct network_address *)network_data_iterator->data;+ if(addr->netaddr->sin->sa.sa_family == AF_INET)+ session->local_ipv4_addresses =+ session_add_address(session->local_ipv4_addresses, addr);+ else+ session->local_ipv6_addresses =+ session_add_address(session->local_ipv6_addresses, addr);++ network_data_iterator = network_data_iterator->next;+ }++ LOG_FUNC_END(1);+}+#endif /* MOBIKE */diff --git src/session.h src/session.hindex ed6202e..0747754 100644--- src/session.h+++ src/session.h@@ -92,6 +92,41 @@ #define MAX_HALF_OPENED_SESSIONS 2 /**+ * Structure for holding local and remote addresses making pair of addresses+ * in a IP addresses state machine.+ */+struct pair_of_addresses {+ /**+ * One of initiator's and one of responder's addresses.+ *+ * Those addresses also hold ports!+ */+ struct netaddr *i_addr, *r_addr;++ /**+ * State of address pair in IP Address Pair State Machine.+ *+ * Possible states are:+ *+ * ADDRESS_PAIR_INVALID 0+ * ADDRESS_PAIR_VALID 1+ * ADDRESS_PAIR_NEGOTIATING 2+ * ADDRESS_PAIR_ACTIVE 3+ * ADDRESS_PAIR_TRANSITING 4+ * ADDRESS_PAIR_INEXISTING 5+ *+ * Default state is ADDRESS_PAIR_INVALID.+ */+ guint8 state;++ /**+ * These are the time fields for return routability check timeout.+ */+ GTimeVal rrc_timeout;+ timeout_t *to;+};++/** * In the following structure all the fields marked as transient are * valid only throughout some particular lifetime of IKE SA, e.g. * during cration, rekeying, reautentification, etc.@@ -288,6 +323,24 @@ struct session { */ struct netaddr *i_addr, *r_addr; + /**+ * List of remote peer's IPv4 and IPv6 addresses+ */+ GSList *peer_ipv4_addresses;+ GSList *peer_ipv6_addresses;++ /**+ * List of pair of addresses, their states and timeouts in+ * IP address state machine in MOBIKE.+ * One pair consists of initiator's address and of respodnder's address.+ */+ GSList *pair_of_addresses_list;+ /**+ * Pointer to active address from pair_of_addresses_list list+ * TODO: This variable should replace i_addr and r_addr variables.+ */+ GSList *active_address_pair;+ #ifdef SUPPLICANT /** * Pointer to a structure with EAP states @@ -452,6 +505,35 @@ struct session { */ #ifdef MOBIKE gboolean mobike_supported;++ /**+ * Counter for IKE AUTH exchanges. It serves for determining if+ * particular exchange contains SA payload, hence 1st IKE AUTH+ * exchange.+ */+ guint8 ike_auth_exchange_counter;++ /*+ * Lists of local IP addresses initialized in network_init() function.+ * Temporary pointers are needed for ADDITIONAL_*_ADDRESS notify+ * payloads in IKE AUTH and INFORMATIONAL exchanges.+ */+ GSList *local_ipv4_addresses;+ GSList *local_ipv6_addresses;++ GSList *local_ipv4_addresses_ptr;+ GSList *local_ipv6_addresses_ptr;++ /**+ * FIXME+ * If we are to switch to MOBIKE port (4500) to send IKE_AUTH and+ * it turns out that remote peer does not support MOBIKE for this+ * connection, we need to switch to ports set previously. That+ * could be IKEV2_PORT_NATT (4500), default port (500) as well as+ * any other set by any party+ */+ guint16 previous_port_i;+ guint16 previous_port_r; #endif /* MOBIKE */ #ifdef CFG_CLIENT@@ -537,19 +619,6 @@ struct session { * pass). This complicates code with many #ifdef's and if's. */ union sm_msg *embedded_sm_msg;-- /**- * FIXME- * If we are to switch to MOBIKE port (4500) to send IKE_AUTH and- * it turns out that remote peer does not support MOBIKE for this- * connection, we need to switch to ports set previously. That- * could be IKEV2_PORT_NATT (4500), default port (500) as well as- * any other set by any party- */-#ifdef MOBIKE- guint16 previous_port_i;- guint16 previous_port_r;-#endif /* MOBIKE */ }; /*******************************************************************************@@ -661,6 +730,8 @@ struct sad_item *session_sad_item_find_by_msg_id(struct session *, guint32); int session_crypto_material(struct session *); gboolean session_use_radius(struct session *);++GSList *session_add_peer_address(struct session *, struct netaddr *); /******************************************************************************* * DEBUG METHODS ******************************************************************************/diff --git src/sm.c src/sm.cindex 25df5f2..368a00d 100644--- src/sm.c+++ src/sm.c@@ -4420,7 +4420,7 @@ int sm_ike_i_thread(struct session *session, union sm_msg *sm_msg) } /*- * Check if we received notify INVALID_SYNTAX. In that case+ * Check if we received notify NO_PROPOSAL_CHOSEN. In that case * terminate IKE SA.. */ if (sm_msg->message_msg.ike_sa_init.no_proposal_chosen) {