/* This will immediately close a server socket and clean out any pending * requests that are waiting on that socket. * */ void force_disconnect(jsonrpc_server_t* server) { if(!server) { ERR("Trying to disconnect a NULL server.\n"); return; } // clear the netstring buffer when disconnecting free_netstring(server->buffer); server->buffer = NULL; server->status = JSONRPC_SERVER_DISCONNECTED; // close bufferevent bev_disconnect(server->bev); INFO("Disconnected from server %.*s:%d for conn %.*s.\n", STR(server->addr), server->port, STR(server->conn)); /* clean out requests */ jsonrpc_request_t* req = NULL; int key = 0; for (key=0; key < JSONRPC_DEFAULT_HTABLE_SIZE; key++) { for (req = request_table[key]; req != NULL; req = req->next) { if(req->server != NULL && req->server == server) { fail_request(JRPC_ERR_SERVER_DISCONNECT, req, "Failing request for server shutdown"); } } } }
void bev_read_cb(struct bufferevent* bev, void* arg) { jsonrpc_server_t* server = (jsonrpc_server_t*)arg; int retval = 0; while (retval == 0) { int retval = netstring_read_evbuffer(bev, &server->buffer); if (retval == NETSTRING_INCOMPLETE) { return; } else if (retval < 0) { char* msg = ""; switch(retval) { case NETSTRING_ERROR_TOO_LONG: msg = "too long"; break; case NETSTRING_ERROR_NO_COLON: msg = "no colon after length field"; break; case NETSTRING_ERROR_TOO_SHORT: msg = "too short"; break; case NETSTRING_ERROR_NO_COMMA: msg = "missing comma"; break; case NETSTRING_ERROR_LEADING_ZERO: msg = "length field has a leading zero"; break; case NETSTRING_ERROR_NO_LENGTH: msg = "missing length field"; break; case NETSTRING_INCOMPLETE: msg = "incomplete"; break; default: ERR("bad netstring: unknown error (%d)\n", retval); goto reconnect; } ERR("bad netstring: %s\n", msg); reconnect: force_reconnect(server); return; } handle_netstring(server); free_netstring(server->buffer); server->buffer = NULL; } }