Implemented handling of UNITY_LOAD_BALANCE as reauthentication.
authorTobias Brunner <tobias@strongswan.org>
Fri, 2 Mar 2012 18:17:13 +0000 (19:17 +0100)
committerTobias Brunner <tobias@strongswan.org>
Tue, 20 Mar 2012 16:31:40 +0000 (17:31 +0100)
src/libcharon/sa/ikev1/task_manager_v1.c
src/libcharon/sa/ikev1/tasks/informational.c

index 1c9b43a..b58e501 100755 (executable)
@@ -1255,6 +1255,23 @@ METHOD(task_manager_t, queue_ike_reauth, void,
        }
        enumerator->destroy(enumerator);
 
+       if (!new->get_child_count(new))
+       {       /* check if a Quick Mode task is queued (UNITY_LOAD_BALANCE case) */
+               task_t *task;
+
+               enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
+               while (enumerator->enumerate(enumerator, &task))
+               {
+                       if (task->get_type(task) == TASK_QUICK_MODE)
+                       {
+                               this->queued_tasks->remove_at(this->queued_tasks, enumerator);
+                               task->migrate(task, new);
+                               new->queue_task(new, task);
+                       }
+               }
+               enumerator->destroy(enumerator);
+       }
+
        if (new->initiate(new, NULL, 0, NULL, NULL) != DESTROY_ME)
        {
                charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
index a521aee..266d47f 100755 (executable)
@@ -83,15 +83,23 @@ METHOD(task_t, process_r, status_t,
                                }
                                else if (type == UNITY_LOAD_BALANCE)
                                {
-                                       host_t *redirect;
+                                       host_t *redirect, *me;
                                        chunk_t data;
 
                                        data = notify->get_notification_data(notify);
-                                       redirect = host_create_from_chunk(AF_INET, data, 0);
+                                       redirect = host_create_from_chunk(AF_INET, data,
+                                                                                                         IKEV2_UDP_PORT);
                                        if (redirect)
-                                       {
+                                       {       /* treat the redirect as reauthentication */
                                                DBG1(DBG_IKE, "received %N notify. redirected to %H",
                                                         notify_type_names, type, redirect);
+                                               /* Cisco boxes reject the first message from 4500 */
+                                               me = this->ike_sa->get_my_host(this->ike_sa);
+                                               me->set_port(me, IKEV2_UDP_PORT);
+                                               this->ike_sa->set_other_host(this->ike_sa, redirect);
+                                               this->ike_sa->reauth(this->ike_sa);
+                                               enumerator->destroy(enumerator);
+                                               return DESTROY_ME;
                                        }
                                        else
                                        {