+ r = compat_recv (fd, pkt->rpkt->data, RS_MAX_PACKET_LEN, MSG_TRUNC);
+ if (r == -1)
+ {
+ int sockerr = evutil_socket_geterror (pkt->conn->fd);
+ if (sockerr == EAGAIN)
+ {
+ /* FIXME: Really shouldn't happen since we've been told
+ that fd is readable! */
+ rs_debug (("%s: EAGAIN reading UDP packet -- wot?\n"));
+ goto err_out;
+ }
+
+ /* Hard error. */
+ rs_err_conn_push_fl (pkt->conn, RSE_SOCKERR, __FILE__, __LINE__,
+ "%d: recv: %d (%s)", fd, sockerr,
+ evutil_socket_error_to_string (sockerr));
+ event_del (pkt->conn->tev);
+ goto err_out;
+ }
+ event_del (pkt->conn->tev);
+ if (r < 20 || r > RS_MAX_PACKET_LEN) /* Short or long packet. */
+ {
+ rs_err_conn_push (pkt->conn, RSE_INVALID_PKT,
+ "invalid packet length: %d", r);
+ goto err_out;
+ }
+ pkt->rpkt->length = (pkt->rpkt->data[2] << 8) + pkt->rpkt->data[3];
+ err = nr_packet_ok (pkt->rpkt);
+ if (err)
+ {
+ rs_err_conn_push_fl (pkt->conn, -err, __FILE__, __LINE__,
+ "invalid packet");
+ goto err_out;
+ }
+ /* Hand over message to user. This changes ownership of pkt.
+ Don't touch it afterwards -- it might have been freed. */
+ if (pkt->conn->callbacks.received_cb)
+ pkt->conn->callbacks.received_cb (pkt, pkt->conn->user_data);
+ else
+ rs_debug (("%s: no received-callback -- dropping packet\n", __func__));