void rclose(struct rtpp_session *sp, void *rrc, int keep) { if (RRC_CAST(rrc)->mode != MODE_REMOTE_RTP && RRC_CAST(rrc)->rbuf_len > 0) flush_rbuf(sp, rrc); if (RRC_CAST(rrc)->fd != -1) close(RRC_CAST(rrc)->fd); if (RRC_CAST(rrc)->mode == MODE_REMOTE_RTP) return; if (keep == 0) { if (unlink(RRC_CAST(rrc)->spath) == -1) rtpp_log_ewrite(RTPP_LOG_ERR, sp->log, "can't remove " "session record %s", RRC_CAST(rrc)->spath); } else if (RRC_CAST(rrc)->needspool == 1) { if (rename(RRC_CAST(rrc)->spath, RRC_CAST(rrc)->rpath) == -1) rtpp_log_ewrite(RTPP_LOG_ERR, sp->log, "can't move " "session record from spool into permanent storage"); } free(rrc); }
void rwrite(struct rtpp_session *sp, void *rrc, struct sockaddr *saddr, void *buf, int len) { struct iovec v[2]; struct pkt_hdr hdr; int rval; if (RRC_CAST(rrc)->fd == -1) return; memset(&hdr, 0, sizeof(hdr)); hdr.time = getctime(); if (hdr.time == -1) { rtpp_log_ewrite(RTPP_LOG_ERR, sp->log, "can't get current time"); goto fatal_error; } switch (saddr->sa_family) { case AF_INET: hdr.addr.in4.sin_family = saddr->sa_family; hdr.addr.in4.sin_port = satosin(saddr)->sin_port; hdr.addr.in4.sin_addr = satosin(saddr)->sin_addr; break; case AF_INET6: hdr.addr.in6.sin_family = saddr->sa_family; hdr.addr.in6.sin_port = satosin6(saddr)->sin6_port; hdr.addr.in6.sin_addr = satosin6(saddr)->sin6_addr; break; default: abort(); } hdr.plen = len; v[0].iov_base = (void *)&hdr; v[0].iov_len = sizeof(hdr); v[1].iov_base = buf; v[1].iov_len = len; rval = writev(RRC_CAST(rrc)->fd, v, 2); if (rval != -1) return; rtpp_log_ewrite(RTPP_LOG_ERR, sp->log, "error while recording session (%s)", (sp->rtcp != NULL) ? "RTP" : "RTCP"); fatal_error: /* Prevent futher writing if error happens */ close(RRC_CAST(rrc)->fd); RRC_CAST(rrc)->fd = -1; }
void rclose(struct rtpp_session *sp, void *rrc) { if (RRC_CAST(rrc)->fd != -1) close(RRC_CAST(rrc)->fd); if (RRC_CAST(rrc)->needspool == 1) if (rename(RRC_CAST(rrc)->spath, RRC_CAST(rrc)->rpath) == -1) rtpp_log_ewrite(RTPP_LOG_ERR, sp->log, "can't move " "session record from spool into permanent storage"); free(rrc); }
static int flush_rbuf(struct rtpp_session *sp, void *rrc) { int rval; rval = write(RRC_CAST(rrc)->fd, RRC_CAST(rrc)->rbuf, RRC_CAST(rrc)->rbuf_len); if (rval != -1) { RRC_CAST(rrc)->rbuf_len = 0; return 0; } rtpp_log_ewrite(RTPP_LOG_ERR, sp->log, "error while recording session (%s)", (sp->rtcp != NULL) ? "RTP" : "RTCP"); /* Prevent futher writing if error happens */ close(RRC_CAST(rrc)->fd); RRC_CAST(rrc)->fd = -1; return -1; }
void rwrite(struct rtpp_session *sp, void *rrc, struct rtp_packet *packet, struct sockaddr *daddr, struct sockaddr *ldaddr, int ldport, int face) { struct iovec v[2]; union { union pkt_hdr_pcap pcap; struct pkt_hdr_adhoc adhoc; } hdr; int rval, hdr_size; int (*prepare_pkt_hdr)(struct rtpp_session *, struct rtp_packet *, void *, struct sockaddr *, struct sockaddr *, int, int); if (RRC_CAST(rrc)->fd == -1) return; switch (RRC_CAST(rrc)->mode) { case MODE_REMOTE_RTP: send(RRC_CAST(rrc)->fd, packet->data.buf, packet->size, 0); return; case MODE_LOCAL_PKT: hdr_size = sizeof(hdr.adhoc); prepare_pkt_hdr = (void *)&prepare_pkt_hdr_adhoc; break; case MODE_LOCAL_PCAP: #if (PCAP_FORMAT == DLT_NULL) hdr_size = sizeof(hdr.pcap.null); #else hdr_size = sizeof(hdr.pcap.en10t); #endif prepare_pkt_hdr = (void *)&prepare_pkt_hdr_pcap; break; } /* Check if the write buffer has necessary space, and flush if not */ if ((RRC_CAST(rrc)->rbuf_len + hdr_size + packet->size > sizeof(RRC_CAST(rrc)->rbuf)) && RRC_CAST(rrc)->rbuf_len > 0) if (flush_rbuf(sp, rrc) != 0) return; face = (sp->record_single_file == 0) ? 0 : face; /* Check if received packet doesn't fit into the buffer, do synchronous write if so */ if (RRC_CAST(rrc)->rbuf_len + hdr_size + packet->size > sizeof(RRC_CAST(rrc)->rbuf)) { if (prepare_pkt_hdr(sp, packet, (void *)&hdr, daddr, ldaddr, ldport, face) != 0) return; v[0].iov_base = (void *)&hdr; v[0].iov_len = hdr_size; v[1].iov_base = packet->data.buf; v[1].iov_len = packet->size; rval = writev(RRC_CAST(rrc)->fd, v, 2); if (rval != -1) return; rtpp_log_ewrite(RTPP_LOG_ERR, sp->log, "error while recording session (%s)", (sp->rtcp != NULL) ? "RTP" : "RTCP"); /* Prevent futher writing if error happens */ close(RRC_CAST(rrc)->fd); RRC_CAST(rrc)->fd = -1; return; } if (prepare_pkt_hdr(sp, packet, (void *)(RRC_CAST(rrc)->rbuf + RRC_CAST(rrc)->rbuf_len), daddr, ldaddr, ldport, face) != 0) return; RRC_CAST(rrc)->rbuf_len += hdr_size; memcpy(RRC_CAST(rrc)->rbuf + RRC_CAST(rrc)->rbuf_len, packet->data.buf, packet->size); RRC_CAST(rrc)->rbuf_len += packet->size; }