/* 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");
			}
		}
	}
}
示例#2
0
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;
	}
}