All pastes #1946574 Raw Edit

ikev2

public diff v1 · immutable
#1946574 ·published 2010-09-22 15:00 UTC
rendered paste body
diff --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) {