diff --git a/src/client.c b/src/client.c index f8a8a50..7fd24e2 100644 --- a/src/client.c +++ b/src/client.c @@ -60,6 +60,10 @@ rudp_error_t rudp_client_connect(struct rudp_client *client) rudp_error_t rudp_client_close(struct rudp_client *client) { + /* Avoid SEGFAULT in case rudp_client_connect() hasn't been called yet. */ + if (client->peer.endpoint == NULL) + return 0; + rudp_peer_send_close_noqueue(&client->peer); rudp_peer_deinit(&client->peer); @@ -70,6 +74,7 @@ rudp_error_t rudp_client_close(struct rudp_client *client) rudp_error_t rudp_client_deinit(struct rudp_client *client) { + rudp_address_deinit(&client->address); rudp_endpoint_deinit(&client->endpoint); return 0; } diff --git a/src/peer.c b/src/peer.c index 456049a..6c39ef4 100644 --- a/src/peer.c +++ b/src/peer.c @@ -101,8 +101,12 @@ void rudp_peer_deinit(struct rudp_peer *peer) { rudp_peer_reset(peer); rudp_address_deinit(&peer->address); - ela_source_free(peer->rudp->el, peer->service_source); - peer->service_source = NULL; + + /* Avoid SEGFAULT in case rudp_peer_deinit() is called more than once. */ + if (peer->service_source != NULL) { + ela_source_free(peer->rudp->el, peer->service_source); + peer->service_source = NULL; + } } static void peer_update_rtt(struct rudp_peer *peer, rudp_time_t last_rtt) @@ -334,6 +338,7 @@ rudp_error_t rudp_peer_incoming_packet( struct rudp_peer *peer, struct rudp_packet_chain *pc) { const struct rudp_packet_header *header = &pc->packet->header; + struct rudp *rudp; rudp_log_printf(peer->rudp, RUDP_LOG_IO, "<<< incoming [%d] %s %s (%d) %04x:%04x\n", @@ -395,9 +400,12 @@ rudp_error_t rudp_peer_incoming_packet( switch ( header->command ) { case RUDP_CMD_CLOSE: + /* Save "rudp" here because "peer" might be freed at the dropped() + * handler (server). */ + rudp = peer->rudp; peer->state = PEER_DEAD; peer->handler->dropped(peer); - rudp_log_printf(peer->rudp, RUDP_LOG_INFO, + rudp_log_printf(rudp, RUDP_LOG_INFO, " peer dropped\n"); return 0; @@ -610,8 +618,10 @@ rudp_error_t rudp_peer_send_connect(struct rudp_peer *peer) { struct rudp_packet_chain *pc = rudp_packet_chain_alloc( peer->rudp, sizeof(struct rudp_packet_conn_req)); + struct rudp_packet_conn_req *conn_req = &pc->packet->conn_req; - pc->packet->header.command = RUDP_CMD_CONN_REQ; + conn_req->header.command = RUDP_CMD_CONN_REQ; + conn_req->data = 0; peer->state = PEER_CONNECTING; @@ -652,6 +662,8 @@ static void peer_send_queue(struct rudp_peer *peer) header->opt |= RUDP_OPT_ACK; header->reliable_ack = htons(peer->in_seq_reliable); // peer->must_ack = 0; + } else { + header->reliable_ack = 0; } rudp_log_printf(peer->rudp, RUDP_LOG_IO,