static int stream_sock_alloc(struct stream *s, int af) { struct sa laddr; int tos, err; if (!s) return EINVAL; /* we listen on all interfaces */ sa_init(&laddr, sa_af(net_laddr_af(af))); err = rtp_listen(&s->rtp, IPPROTO_UDP, &laddr, config.avt.rtp_ports.min, config.avt.rtp_ports.max, s->rtcp, rtp_recv, rtcp_handler, s); if (err) return err; tos = config.avt.rtp_tos; (void)udp_setsockopt(rtp_sock(s->rtp), IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); (void)udp_setsockopt(rtcp_sock(s->rtp), IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); udp_rxsz_set(rtp_sock(s->rtp), RTP_RECV_SIZE); return 0; }
static int stream_sock_alloc(struct stream *s, int af) { struct sa laddr; int tos, err; if (!s) return EINVAL; /* we listen on all interfaces */ sa_init(&laddr, af); err = rtp_listen(&s->rtp, IPPROTO_UDP, &laddr, s->cfg.rtp_ports.min, s->cfg.rtp_ports.max, s->rtcp, rtp_recv, rtcp_handler, s); if (err) { warning("stream: rtp_listen failed: af=%s ports=%u-%u" " (%m)\n", net_af2name(af), s->cfg.rtp_ports.min, s->cfg.rtp_ports.max, err); return err; } tos = s->cfg.rtp_tos; (void)udp_setsockopt(rtp_sock(s->rtp), IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); (void)udp_setsockopt(rtcp_sock(s->rtp), IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); udp_rxsz_set(rtp_sock(s->rtp), RTP_RECV_SIZE); return 0; }
int main(int argc, char *argv[]) { struct sa nsv[16]; struct dnsc *dnsc = NULL; struct sa laddr; uint32_t nsc; int err; /* errno return values */ /* enable coredumps to aid debugging */ (void)sys_coredump_set(true); /* initialize libre state */ err = libre_init(); if (err) { re_fprintf(stderr, "re init failed: %s\n", strerror(err)); goto out; } nsc = ARRAY_SIZE(nsv); /* fetch list of DNS server IP addresses */ err = dns_srv_get(NULL, 0, nsv, &nsc); if (err) { re_fprintf(stderr, "unable to get dns servers: %s\n", strerror(err)); goto out; } /* create DNS client */ err = dnsc_alloc(&dnsc, NULL, nsv, nsc); if (err) { re_fprintf(stderr, "unable to create dns client: %s\n", strerror(err)); goto out; } /* create SIP stack instance */ err = sip_alloc(&sip, dnsc, 32, 32, 32, "ua demo v" VERSION " (" ARCH "/" OS ")", exit_handler, NULL); if (err) { re_fprintf(stderr, "sip error: %s\n", strerror(err)); goto out; } /* fetch local IP address */ err = net_default_source_addr_get(AF_INET, &laddr); if (err) { re_fprintf(stderr, "local address error: %s\n", strerror(err)); goto out; } /* listen on random port */ sa_set_port(&laddr, 0); /* add supported SIP transports */ err |= sip_transp_add(sip, SIP_TRANSP_UDP, &laddr); err |= sip_transp_add(sip, SIP_TRANSP_TCP, &laddr); if (err) { re_fprintf(stderr, "transport error: %s\n", strerror(err)); goto out; } /* create SIP session socket */ err = sipsess_listen(&sess_sock, sip, 32, connect_handler, NULL); if (err) { re_fprintf(stderr, "session listen error: %s\n", strerror(err)); goto out; } /* create the RTP/RTCP socket */ err = rtp_listen(&rtp, IPPROTO_UDP, &laddr, 10000, 30000, true, rtp_handler, rtcp_handler, NULL); if (err) { re_fprintf(stderr, "rtp listen error: %m\n", err); goto out; } re_printf("local RTP port is %u\n", sa_port(rtp_local(rtp))); /* create SDP session */ err = sdp_session_alloc(&sdp, &laddr); if (err) { re_fprintf(stderr, "sdp session error: %s\n", strerror(err)); goto out; } /* add audio sdp media, using port from RTP socket */ err = sdp_media_add(&sdp_media, sdp, "audio", sa_port(rtp_local(rtp)), "RTP/AVP"); if (err) { re_fprintf(stderr, "sdp media error: %s\n", strerror(err)); goto out; } /* add G.711 sdp media format */ err = sdp_format_add(NULL, sdp_media, false, "0", "PCMU", 8000, 1, NULL, NULL, NULL, false, NULL); if (err) { re_fprintf(stderr, "sdp format error: %s\n", strerror(err)); goto out; } /* invite provided URI */ if (argc > 1) { struct mbuf *mb; /* create SDP offer */ err = sdp_encode(&mb, sdp, true); if (err) { re_fprintf(stderr, "sdp encode error: %s\n", strerror(err)); goto out; } err = sipsess_connect(&sess, sess_sock, argv[1], name, uri, name, NULL, 0, "application/sdp", mb, auth_handler, NULL, false, offer_handler, answer_handler, progress_handler, establish_handler, NULL, NULL, close_handler, NULL, NULL); mem_deref(mb); /* free SDP buffer */ if (err) { re_fprintf(stderr, "session connect error: %s\n", strerror(err)); goto out; } re_printf("inviting <%s>...\n", argv[1]); } else { err = sipreg_register(®, sip, registrar, uri, uri, 60, name, NULL, 0, 0, auth_handler, NULL, false, register_handler, NULL, NULL, NULL); if (err) { re_fprintf(stderr, "register error: %s\n", strerror(err)); goto out; } re_printf("registering <%s>...\n", uri); } /* main loop */ err = re_main(signal_handler); out: /* clean up/free all state */ mem_deref(sdp); /* will also free sdp_media */ mem_deref(rtp); mem_deref(sess_sock); mem_deref(sip); mem_deref(dnsc); /* free librar state */ libre_close(); /* check for memory leaks */ tmr_debug(); mem_debug(); return err; }