+ assert (!conn_user_dispatch_p (conn)); /* This function is high level. */
+
+ gettimeofday (&end, NULL);
+ end.tv_sec += MRD;
+ _rand_rt (&rt, IRT, RAND);
+ while (1)
+ {
+ rs_conn_set_timeout (conn, &rt);
+
+ r = rs_packet_send (request->req_msg, NULL);
+ if (r == RSE_OK)
+ {
+ r = rs_conn_receive_packet (request->conn,
+ request->req_msg,
+ resp_msg);
+ if (r == RSE_OK)
+ break; /* Success. */
+
+ if (r != RSE_TIMEOUT_CONN && r != RSE_TIMEOUT_IO)
+ break; /* Error. */
+ }
+ else if (r != RSE_TIMEOUT_CONN && r != RSE_TIMEOUT_IO)
+ break; /* Error. */
+
+ gettimeofday (&now, NULL);
+ if (++count > MRC || timercmp (&now, &end, >))
+ {
+ r = RSE_TIMEOUT;
+ break; /* Timeout. */
+ }
+
+ /* rt = 2 * rt + rand_rt (rt, RAND); */
+ timeradd (&rt, &rt, &rt);
+ _rand_rt (&tmp_tv, IRT, RAND);
+ timeradd (&rt, &tmp_tv, &rt);
+ if (timercmp (&rt, &mrt_tv, >))
+ _rand_rt (&rt, MRT, RAND);
+ }
+
+ timerclear (&rt);
+ rs_conn_set_timeout (conn, &rt);
+
+ rs_debug (("%s: returning %d\n", __func__, r));
+ return r;
+}