00001 #include "hub.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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;
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 }