added SSL backend for IOMultiplexer
[TransparentIRC.git] / src / UserSession.c
index 8b90299df4dcf40fac073954edff9fd9db1240e9..e66d6e6ae93864c168bddb67f7b4bd440a2e01e1 100644 (file)
@@ -41,10 +41,14 @@ static struct UserSession *usersession_add(char *username, char *password, char
 }
 
 static void usersession_close(struct UserSession *session) {
-    if(session->client)
+    if(session->client) {
+        session->client->user = NULL;
         userclient_close(session->client);
+    }
     if(session->irc)
         ircclient_close(session->irc);
+    if(session->timer)
+        iohandler_close(session->timer);
     
     if(session->prev)
         session->prev->next = session->next;
@@ -62,6 +66,8 @@ static void usersession_close(struct UserSession *session) {
 
 /* ****************** EXTERNAL EVENTS ****************** */
 
+static void usersession_timer_callback(struct IOEvent *event);
+
 void usersession_error(struct UserSession *session, char *error) {
     if(session->client) {
         iohandler_printf(session->client->iofd, ":*TransparentIRC!TransIRC@TransparentIRC.system.notification NOTICE %s :[TransparentIRC] ERROR: %s", session->nick, error);
@@ -71,8 +77,21 @@ void usersession_error(struct UserSession *session, char *error) {
 
 void usersession_client_close(struct UserSession *session) {
     session->client = NULL;
+    if(!session->irc || !session->irc->fully_connected) {
+        usersession_close(session);
+        return;
+    }
     session->idle_since = time(0);
-    
+    if(!session->timer) {
+        int timeout_sec = get_int_field("session.timeout");
+        if(timeout_sec) {
+            struct timeval timeout;
+            gettimeofday(&timeout, NULL);
+            timeout.tv_sec += timeout_sec;
+            session->timer = iohandler_timer(timeout, usersession_timer_callback);
+            session->timer->data = session;
+        }
+    }
 }
 
 void usersession_client_raw(struct UserSession *session, char *raw) {
@@ -87,6 +106,17 @@ void usersession_client_notification(struct UserSession *session, char *notifica
     }
 }
 
+static void usersession_timer_callback(struct IOEvent *event) {
+    struct UserSession *session = event->iofd->data;
+    switch(event->type) {
+        case IOEVENT_TIMEOUT:
+            usersession_close(session);
+            break;
+        default:
+            break;
+    }
+}
+
 /* ****************** LOGIN FUNCTIONS ****************** */
 
 static void usersession_login_accept(struct UserLogin *login);
@@ -114,14 +144,16 @@ void usersession_login(struct UserLogin *login) {
             userclient_login_failed(login, "Login Script error.");
             return;
         }
-        struct IODescriptor *iofd = iohandler_add(fp, IOTYPE_CLIENT, usersession_login_callback);
+        struct IODescriptor *iofd = iohandler_add(fp, IOTYPE_CLIENT, NULL, usersession_login_callback);
         if(iofd) {
             iofd->read_lines = 1;
             iofd->state = IO_CONNECTED;
             int timeout = get_int_field("auth.external.timeout");
             if(timeout) {
-                gettimeofday(&iofd->timeout, NULL);
-                iofd->timeout.tv_sec += timeout;
+                struct timeval tv_timeout;
+                gettimeofday(&tv_timeout, NULL);
+                tv_timeout.tv_sec += timeout;
+                iohandler_set_timeout(iofd, &tv_timeout);
             }
             iofd->data = login;
             login->login_iofd = iofd;
@@ -150,6 +182,10 @@ static void usersession_login_accept(struct UserLogin *login) {
             userclient_close(active_session->client);
         } //active_session->client is now NULL
         active_session->client = login->client;
+        if(active_session->timer) {
+            iohandler_close(active_session->timer);
+            active_session->timer = NULL;
+        }
         userclient_login_successful(login, active_session, 1);
     } else {
         int sessionlimit = get_int_field("auth.session_limit");