Example #1
0
void process_connection(int ci)
{
	struct boothc_header h;
	char *data = NULL;
	char *site, *ticket;
	int local, rv;

	rv = do_read(client[ci].fd, &h, sizeof(h));
	if (rv < 0) {
		log_error("connection %d read error %d", ci, rv);
		return;
	}
	if (h.magic != BOOTHC_MAGIC) {
		log_error("connection %d magic error %x", ci, h.magic);
		return;
	}
	if (h.version != BOOTHC_VERSION) {
		log_error("connection %d version error %x", ci, h.version);
		return;
	}

	if (h.len) {
		data = malloc(h.len);
		if (!data) {
			log_error("process_connection no mem %u", h.len);
			return;
		}
		memset(data, 0, h.len);

		rv = do_read(client[ci].fd, data, h.len);
		if (rv < 0) {
			log_error("connection %d read data error %d", ci, rv);
			goto out;
		}
		h.len = 0;
	}

	switch (h.cmd) {
	case BOOTHC_CMD_LIST:
		assert(!data);
		h.result = list_ticket(&data, &h.len);
		break;

	case BOOTHC_CMD_GRANT:
		site = data;
		ticket = data + BOOTH_NAME_LEN;
		if (!check_ticket(ticket)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (!check_site(site, &local)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (local)
			h.result = grant_ticket(ticket, h.option);
		else
			h.result = BOOTHC_RLT_REMOTE_OP;
		break;

	case BOOTHC_CMD_REVOKE:
		site = data;
		ticket = data + BOOTH_NAME_LEN;
		if (!check_ticket(ticket)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (!check_site(site, &local)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (local)
			h.result = revoke_ticket(ticket, h.option);
		else
			h.result = BOOTHC_RLT_REMOTE_OP;
		break;

	default:
		log_error("connection %d cmd %x unknown", ci, h.cmd);
		break;
	}

reply:
	rv = do_write(client[ci].fd, &h, sizeof(h));
	if (rv < 0)
		log_error("connection %d write error %d", ci, rv);
	if (h.len) {
		rv = do_write(client[ci].fd, data, h.len);
		if (rv < 0)
			log_error("connection %d write error %d", ci, rv);
	}
out:
	free(data);	
}
Example #2
0
File: main.c Project: aspiers/booth
void process_connection(int ci)
{
	struct boothc_header h;
	char *data = NULL;
	char *site, *ticket;
	int local, rv;
	void (*deadfn) (int ci);

	rv = do_read(client[ci].fd, &h, sizeof(h));

	if (rv < 0) {
		if (errno == ECONNRESET)
			log_debug("client %d connection reset for fd %d", ci, client[ci].fd);
		else 
			log_debug("client %d read failed for fd %d: %s (%d)",
				  ci, client[ci].fd,
				  strerror(errno), errno);

		deadfn = client[ci].deadfn;
		if(deadfn) {
			log_debug("run deadfn");
			deadfn(ci);
		}
		return;
	}
	if (h.magic != BOOTHC_MAGIC) {
		log_error("connection %d magic error %x", ci, h.magic);
		return;
	}
	if (h.version != BOOTHC_VERSION) {
		log_error("connection %d version error %x", ci, h.version);
		return;
	}

	if (h.len) {
		data = malloc(h.len);
		if (!data) {
			log_error("process_connection no mem %u", h.len);
			return;
		}
		memset(data, 0, h.len);

		rv = do_read(client[ci].fd, data, h.len);
		if (rv < 0) {
			log_error("connection %d read data error %d", ci, rv);
			goto out;
		}
	}

	switch (h.cmd) {
	case BOOTHC_CMD_LIST:
		assert(!data);
		h.result = list_ticket(&data, &h.len);
		break;

	case BOOTHC_CMD_GRANT:
		h.len = 0;
		site = data;
		ticket = data + BOOTH_NAME_LEN;
		if (!check_ticket(ticket)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (!check_site(site, &local)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (local)
			h.result = grant_ticket(ticket, h.option);
		else
			h.result = BOOTHC_RLT_REMOTE_OP;
		break;

	case BOOTHC_CMD_REVOKE:
		h.len = 0;
		site = data;
		ticket = data + BOOTH_NAME_LEN;
		if (!check_ticket(ticket)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (!check_site(site, &local)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (local)
			h.result = revoke_ticket(ticket, h.option);
		else
			h.result = BOOTHC_RLT_REMOTE_OP;
		break;

	case BOOTHC_CMD_CATCHUP:
		h.result = catchup_ticket(&data, h.len);	
		break;

	default:
		log_error("connection %d cmd %x unknown", ci, h.cmd);
		break;
	}

reply:
	rv = do_write(client[ci].fd, &h, sizeof(h));
	if (rv < 0)
		log_error("connection %d write error %d", ci, rv);
	if (h.len) {
		rv = do_write(client[ci].fd, data, h.len);
		if (rv < 0)
			log_error("connection %d write error %d", ci, rv);
	}
out:
	free(data);	
}