Exemplo n.º 1
0
static
ssize_t dtls_pull(gnutls_transport_ptr_t ptr, void *data, size_t size)
{
	dtls_transport_ptr *p = ptr;

	if (p->msg) {
		ssize_t need = p->msg->data.len;
		if (need > size) {
			need = size;
		}
		memcpy(data, p->msg->data.data, need);

		udp_fd_msg__free_unpacked(p->msg, NULL);
		p->msg = NULL;
		return need;
	}
	return recv(p->fd, data, size, 0);
}
Exemplo n.º 2
0
int handle_commands_from_main(struct worker_st *ws)
{
	uint8_t cmd;
	size_t length;
	uint8_t cmd_data[1536];
	UdpFdMsg *tmsg = NULL;
	int ret;
	int fd = -1;
	/*int cmd_data_len;*/

	memset(&cmd_data, 0, sizeof(cmd_data));

	ret = recv_msg_data(ws->cmd_fd, &cmd, cmd_data, sizeof(cmd_data), &fd);
	if (ret < 0) {
		oclog(ws, LOG_DEBUG, "cannot obtain data from command socket");
		exit_worker_reason(ws, REASON_SERVER_DISCONNECT);
	}

	if (ret == 0) {
		oclog(ws, LOG_ERR, "parent terminated");
		return ERR_NO_CMD_FD;
	}

	length = ret;

	oclog(ws, LOG_DEBUG, "worker received message %s of %u bytes\n", cmd_request_to_str(cmd), (unsigned)length);

	/*cmd_data_len = ret - 1;*/

	switch(cmd) {
		case CMD_TERMINATE:
			exit_worker_reason(ws, REASON_SERVER_DISCONNECT);
		case CMD_UDP_FD: {
			unsigned has_hello = 1;

			if (ws->udp_state != UP_WAIT_FD) {
				oclog(ws, LOG_DEBUG, "received another a UDP fd!");
			}

			tmsg = udp_fd_msg__unpack(NULL, length, cmd_data);
			if (tmsg) {
				has_hello = tmsg->hello;
			}

			if (fd == -1) {
				oclog(ws, LOG_ERR, "received UDP fd message of wrong type");
				goto udp_fd_fail;
			}

			set_non_block(fd);

			if (has_hello == 0) {
				/* check if the first packet received is a valid one -
				 * if not discard the new fd */
				if (!recv_from_new_fd(ws, fd, tmsg)) {
					oclog(ws, LOG_INFO, "received UDP fd message but its session has invalid data!");
					if (tmsg)
						udp_fd_msg__free_unpacked(tmsg, NULL);
					close(fd);
					return 0;
				}
				RESET_DTLS_MTU(ws);
			} else { /* received client hello */
				ws->udp_state = UP_SETUP;
			}

			if (ws->dtls_tptr.fd != -1)
				close(ws->dtls_tptr.fd);
			if (ws->dtls_tptr.msg != NULL)
				udp_fd_msg__free_unpacked(ws->dtls_tptr.msg, NULL);

			ws->dtls_tptr.msg = tmsg;
			ws->dtls_tptr.fd = fd;

			oclog(ws, LOG_DEBUG, "received new UDP fd and connected to peer");
			return 0;

			}
			break;
		default:
			oclog(ws, LOG_ERR, "unknown CMD 0x%x", (unsigned)cmd);
			exit_worker_reason(ws, REASON_ERROR);
	}

	return 0;

udp_fd_fail:
	if (tmsg)
		udp_fd_msg__free_unpacked(tmsg, NULL);
	if (ws->dtls_tptr.fd == -1)
		ws->udp_state = UP_DISABLED;

	return -1;
}