/** Keepalive timer. */ void tport_keepalive_timer(tport_t *self, su_time_t now) { unsigned timeout = self->tp_params->tpp_pingpong; if (timeout != 0) { if (self->tp_ptime.tv_sec && !self->tp_recv_close && su_time_cmp(su_time_add(self->tp_ptime, timeout), now) < 0) { SU_DEBUG_3(("%s(%p): %s to " TPN_FORMAT "%s\n", __func__, (void *)self, "closing connection", TPN_ARGS(self->tp_name), " because of PONG timeout")); tport_error_report(self, EPIPE, NULL); if (!self->tp_closed) tport_close(self); return; } } timeout = self->tp_params->tpp_keepalive; if (timeout != 0 && timeout != UINT_MAX) { if (su_time_cmp(su_time_add(self->tp_ktime, timeout), now) < 0) { tport_tcp_ping(self, now); } } }
/** Send pong */ int tport_ws_pong(tport_t *self) { self->tp_ping = 0; if (tport_has_queued(self) || !self->tp_params->tpp_pong2ping) return 0; SU_DEBUG_7(("%s(%p): %s to " TPN_FORMAT "%s\n", __func__, (void *)self, "sending PONG", TPN_ARGS(self->tp_name), "")); return send(self->tp_socket, "\r\n", 2, 0); }
/** Send PING */ int tport_ws_ping(tport_t *self, su_time_t now) { ssize_t n; char *why = ""; if (tport_has_queued(self)) return 0; n = send(self->tp_socket, "\r\n\r\n", 4, 0); if (n > 0) self->tp_ktime = now; if (n == 4) { if (self->tp_ptime.tv_sec == 0) self->tp_ptime = now; } else if (n == -1) { int error = su_errno(); why = " failed"; if (!su_is_blocking(error)) tport_error_report(self, error, NULL); else why = " blocking"; return -1; } SU_DEBUG_7(("%s(%p): %s to " TPN_FORMAT "%s\n", __func__, (void *)self, "sending PING", TPN_ARGS(self->tp_name), why)); return n == -1 ? -1 : 0; }