hub/connection_state.c

Go to the documentation of this file.
00001 #include "hub.h"
00002 
00003 /*
00004  * Utu -- Saving The Internet With Hate
00005  *
00006  * Copyright (c) Zed A. Shaw 2005 (zedshaw@zedshaw.com)
00007  *
00008  * This file is modifiable/redistributable under the terms of the GNU
00009  * General Public License.
00010  *
00011  * You should have recieved a copy of the GNU General Public License along
00012  * with this program; see the file COPYING. If not, write to the Free Software
00013  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 0211-1307, USA.
00014  */
00015 
00016 void ConnectionState_destroy(ConnectionState *state)
00017 {
00018   free(state);
00019 }
00020 
00021 int ConnectionState_dequeue_msg(ConnectionState *state)
00022 {
00023   if(ConnectionState_done(state)) {
00024     return 0;
00025   }
00026 
00027   state->send.msg = Member_first_msg(state->member);
00028 
00029   return state->send.msg != NULL;
00030 }
00031 
00032 int ConnectionState_send_msg(ConnectionState *state)
00033 {
00034   int rc = 0;
00035   Message *msg = state->send.msg;
00036 
00037   if(ConnectionState_done(state)) {
00038     rc = 0;
00039   } else {
00040     // make a new header with the msgid the connected client expects
00041     Node *hdr = Message_cons_header(msg->circuit, msg->more, state->send_count++);
00042     rc = Peer_send(state->member->peer, hdr, msg->body);
00043     Node_destroy(hdr);
00044   }
00045 
00046   return rc;
00047 }
00048 
00049 void ConnectionState_outgoing(void *data)
00050 {
00051   ConnectionState *state = (ConnectionState *)data;
00052 
00053   while(ConnectionState_dequeue_msg(state)) {
00054     ConnectionState_lock(state);
00055 
00056     if(ConnectionState_exec(state, UEv_MSG_QUEUED) == 0) {
00057       if(ConnectionState_send_msg(state)) {
00058         ConnectionState_exec(state, UEv_MSG_SENT);
00059       } else {
00060         ConnectionState_exec(state, UEv_FAIL);
00061         break; // abort on any error
00062       }
00063     }
00064 
00065     ConnectionState_unlock(state);
00066   }
00067 
00068   ConnectionState_exec(state, UEv_WRITE_CLOSE);
00069 }
00070 
00071 
00072 int ConnectionState_confirm_key(CryptState *state)
00073 {
00074   return ConnectionState_exec((ConnectionState *)(state->data), UEv_PASS) == 0;
00075 }
00076 
00077 int ConnectionState_read_msg(ConnectionState *state)
00078 {
00079   if(ConnectionState_done(state) || state->client == NULL) return 0;
00080 
00081   state->recv.body = Peer_recv(state->member->peer, &(state->recv.hdr));
00082 
00083   return state->recv.body != NULL;
00084 }
00085 
00086 void ConnectionState_incoming(void *data)
00087 {
00088   ConnectionState *state = (ConnectionState *)data;
00089 
00090   ConnectionState_exec(state, UEv_KEY_PRESENT);
00091   ConnectionState_exec(state, UEv_PASS);
00092   ConnectionState_exec(state, UEv_PASS);
00093 
00094   while(ConnectionState_read_msg(state)) {
00095     ConnectionState_lock(state);
00096 
00097     if(ConnectionState_exec(state, UEv_MSG_RECV) == 0 && state->recv.msg) {
00098       if(state->recv.msg->circuit == 0) {
00099         ConnectionState_exec(state, UEv_SVC_RECV);
00100       } else {
00101         ConnectionState_exec(state, UEv_MSG_QUEUED);
00102       }
00103     } 
00104 
00105     ConnectionState_unlock(state);
00106   }
00107 
00108   ConnectionState_exec(state, UEv_READ_CLOSE);
00109 }
00110 
00111 
00112 int ConnectionState_half_close(ConnectionState *state)
00113 {
00114   if(state->client) {
00115     server_destroy_client(state->client);
00116     state->client = NULL;
00117 
00118     if(state->member) {
00119       Route_unregister_all(state->hub->routes, state->member);
00120       Member_logout(&state->hub->members, state->member);
00121     }
00122 
00123     state->member = NULL;
00124     return 1;
00125   } else {
00126     return 0;
00127   }
00128 }
00129 
00130 int ConnectionState_rest_close(ConnectionState *state)
00131 {
00132   assert(state->client == NULL && "Attempting to call rest_close before half_close called.");
00133 
00134   if(state->hub->closed != state) {
00135     SGLIB_LIST_ADD(ConnectionState, state->hub->closed, state, next);
00136     return 1;
00137   } else {
00138     return 0;
00139   }
00140 }

Generated on Tue Apr 10 01:00:18 2007 for Utu by  doxygen 1.5.1