Decode JSON TRP messages, then send to main thread.
[trust_router.git] / trp / trp_conn.c
index c7f3d30..1065116 100644 (file)
@@ -45,7 +45,7 @@ TRP_CONNECTION_STATUS trp_connection_get_status(TRP_CONNECTION *conn)
   return status;
 }
 
-void trp_connection_set_status(TRP_CONNECTION *conn, TRP_CONNECTION_STATUS status)
+static void trp_connection_set_status(TRP_CONNECTION *conn, TRP_CONNECTION_STATUS status)
 {
   pthread_mutex_lock(&(conn->status_mutex));
   conn->status=status;
@@ -72,6 +72,37 @@ static void trp_connection_set_next(TRP_CONNECTION *conn, TRP_CONNECTION *next)
   conn->next=next;
 }
 
+/* Ok to call more than once; guarantees connection no longer in the list.
+ * Returns handle to new list, you must replace your old handle on the list with this.  */
+TRP_CONNECTION *trp_connection_remove(TRP_CONNECTION *conn, TRP_CONNECTION *remove)
+{
+  TRP_CONNECTION *cur=conn;
+  TRP_CONNECTION *last=NULL;
+
+  if (cur==NULL)
+    return NULL;
+
+  /* first element is a special case */
+  if (cur==remove) {
+    conn=trp_connection_get_next(cur); /* advance list head */
+    trp_connection_free(cur);
+  } else {
+    /* it was not the first element */
+    last=cur;
+    cur=trp_connection_get_next(cur);
+    while (cur!=NULL) {
+      if (cur==remove) {
+        trp_connection_set_next(last, trp_connection_get_next(cur));
+        trp_connection_free(cur);
+        break;
+      }
+      last=cur;
+      cur=trp_connection_get_next(cur);
+    }
+  }
+  return conn;
+}
+
 static TRP_CONNECTION *trp_connection_get_tail(TRP_CONNECTION *conn)
 {
   while((conn!=NULL)&&(trp_connection_get_next(conn)!=NULL))
@@ -115,17 +146,17 @@ TRP_CONNECTION *trp_connection_new(TALLOC_CTX *mem_ctx)
     trp_connection_mutex_init(new_conn);
     trp_connection_set_status(new_conn, TRP_CONNECTION_DOWN);
     thread=talloc(new_conn, pthread_t);
-    if (thread==NULL) {
-      talloc_free(new_conn);
-      return NULL;
-    }
-    trp_connection_set_thread(new_conn, thread);
     gssctx=talloc(new_conn, gss_ctx_id_t);
     if (gssctx==NULL) {
       talloc_free(new_conn);
       return NULL;
     }
     trp_connection_set_gssctx(new_conn, gssctx);
+    if (thread==NULL) {
+      talloc_free(new_conn);
+      return NULL;
+    }
+    trp_connection_set_thread(new_conn, thread);
     talloc_set_destructor((void *)new_conn, trp_connection_destructor);
   }
   return new_conn;
@@ -133,10 +164,15 @@ TRP_CONNECTION *trp_connection_new(TALLOC_CTX *mem_ctx)
 
 void trp_connection_free(TRP_CONNECTION *conn)
 {
-  /* TODO: shut down connection if it is still open */
   talloc_free(conn);
 }
 
+void trp_connection_close(TRP_CONNECTION *conn)
+{
+  close(trp_connection_get_fd(conn));
+  trp_connection_set_fd(conn, -1);
+  trp_connection_set_status(conn, TRP_CONNECTION_DOWN);
+}
 
 /* returns 0 on authorization success, 1 on failure, or -1 in case of error */
 int trp_connection_auth(TRP_CONNECTION *conn, TRP_AUTH_FUNC auth_callback, void *callback_data)
@@ -144,20 +180,22 @@ int trp_connection_auth(TRP_CONNECTION *conn, TRP_AUTH_FUNC auth_callback, void
   int rc = 0;
   int auth, autherr = 0;
   gss_buffer_desc nameBuffer = {0, NULL};
-  gss_ctx_id_t gssctx;
+  gss_ctx_id_t *gssctx=trp_connection_get_gssctx(conn);
 
   /* TODO: shouldn't really peek into TR_NAME... */
   nameBuffer.length = trp_connection_get_gssname(conn)->len;
   nameBuffer.value = trp_connection_get_gssname(conn)->buf;
 
   tr_debug("trp_connection_auth: beginning passive authentication");
-  if (rc = gsscon_passive_authenticate(trp_connection_get_fd(conn), nameBuffer, &gssctx, auth_callback, callback_data)) {
+  rc = gsscon_passive_authenticate(trp_connection_get_fd(conn), nameBuffer, gssctx, auth_callback, callback_data);
+  gss_release_buffer(NULL, &nameBuffer);
+  if (rc!=0) {
     tr_debug("trp_connection_auth: Error from gsscon_passive_authenticate(), rc = 0x%08X.", rc);
     return -1;
   }
 
   tr_debug("trp_connection_auth: beginning second stage authentication");
-  if (rc = gsscon_authorize(gssctx, &auth, &autherr)) {
+  if (rc = gsscon_authorize(*gssctx, &auth, &autherr)) {
     tr_debug("trp_connection_auth: Error from gsscon_authorize, rc = %d, autherr = %d.", 
              rc, autherr);
     return -1;
@@ -172,8 +210,7 @@ int trp_connection_auth(TRP_CONNECTION *conn, TRP_AUTH_FUNC auth_callback, void
 }
 
 /* Accept connection */
-TRP_CONNECTION *trp_connection_accept(TALLOC_CTX *mem_ctx, int listen, TR_NAME *gssname, TRP_AUTH_FUNC auth_handler, TRP_REQ_FUNC req_handler,
-                                      void *cookie)
+TRP_CONNECTION *trp_connection_accept(TALLOC_CTX *mem_ctx, int listen, TR_NAME *gssname)
 {
   int conn_fd=-1;
   TRP_CONNECTION *conn=NULL;
@@ -187,6 +224,7 @@ TRP_CONNECTION *trp_connection_accept(TALLOC_CTX *mem_ctx, int listen, TR_NAME *
   conn=trp_connection_new(mem_ctx);
   trp_connection_set_fd(conn, conn_fd);
   trp_connection_set_gssname(conn, gssname);
+  trp_connection_set_status(conn, TRP_CONNECTION_UP);
   return conn;
 }