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); }
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; }