/** @brief RTP payload type */
static int rtp_payload;
-/** @brief RTP output socket */
-static int rtp_fd;
+/** @brief RTP broadcast/multicast output socket */
+static int rtp_fd = -1;
-/** @brief RTP output socket (IPv6) */
-static int rtp_fd6;
+/** @brief RTP unicast output socket (IPv4) */
+static int rtp_fd4 = -1;
+
+/** @brief RTP unicast output socket (IPv6) */
+static int rtp_fd6 = -1;
/** @brief RTP SSRC */
static uint32_t rtp_id;
*/
static int rtp_errors;
-/** @brief Set while paused */
-static volatile int rtp_paused;
-
/** @brief RTP mode */
static int rtp_mode;
uaudio_schedule_sent(nsamples);
return nsamples;
}
- if(rtp_mode == RTP_REQUEST) {
- struct rtp_recipient *r;
- struct msghdr m;
- memset(&m, 0, sizeof m);
- m.msg_iov = vec;
- m.msg_iovlen = 2;
- pthread_mutex_lock(&rtp_lock);
- for(r = rtp_recipient_list; r; r = r->next) {
- m.msg_name = &r->sa;
- m.msg_namelen = r->sa.ss_family == AF_INET ?
- sizeof(struct sockaddr_in) : sizeof (struct sockaddr_in6);
- sendmsg(r->sa.ss_family == AF_INET ? rtp_fd : rtp_fd6,
- &m, MSG_DONTWAIT|MSG_NOSIGNAL);
- // TODO similar error handling to other case?
- }
- pthread_mutex_unlock(&rtp_lock);
- } else {
+ /* Send stuff to explicitly registerd unicast addresses unconditionally */
+ struct rtp_recipient *r;
+ struct msghdr m;
+ memset(&m, 0, sizeof m);
+ m.msg_iov = vec;
+ m.msg_iovlen = 2;
+ pthread_mutex_lock(&rtp_lock);
+ for(r = rtp_recipient_list; r; r = r->next) {
+ m.msg_name = &r->sa;
+ m.msg_namelen = r->sa.ss_family == AF_INET ?
+ sizeof(struct sockaddr_in) : sizeof (struct sockaddr_in6);
+ sendmsg(r->sa.ss_family == AF_INET ? rtp_fd4 : rtp_fd6,
+ &m, MSG_DONTWAIT|MSG_NOSIGNAL);
+ // TODO similar error handling to other case?
+ }
+ pthread_mutex_unlock(&rtp_lock);
+ if(rtp_mode != RTP_REQUEST) {
int written_bytes;
do {
written_bytes = writev(rtp_fd, vec, 2);
return nsamples;
}
+static void hack_send_buffer_size(int fd, const char *what) {
+ int sndbuf, target_sndbuf = 131072;
+ socklen_t len = sizeof sndbuf;
+
+ if(getsockopt(fd, SOL_SOCKET, SO_SNDBUF,
+ &sndbuf, &len) < 0)
+ disorder_fatal(errno, "error getting SO_SNDBUF on %s socket", what);
+ if(target_sndbuf > sndbuf) {
+ if(setsockopt(fd, SOL_SOCKET, SO_SNDBUF,
+ &target_sndbuf, sizeof target_sndbuf) < 0)
+ disorder_error(errno, "error setting SO_SNDBUF on %s socket to %d",
+ what, target_sndbuf);
+ else
+ disorder_info("changed socket send buffer size on %socket from %d to %d",
+ what, sndbuf, target_sndbuf);
+ } else
+ disorder_info("default socket send buffer on %s socket is %d",
+ what, sndbuf);
+}
+
static void rtp_open(void) {
struct addrinfo *dres, *sres;
static const int one = 1;
- int sndbuf, target_sndbuf = 131072;
- socklen_t len;
struct netaddress dst[1], src[1];
const char *mode;
rtp_mode = RTP_UNICAST;
}
}
- /* Create the socket */
+ /* Create the sockets */
if(rtp_mode != RTP_REQUEST) {
if((rtp_fd = socket(dres->ai_family,
dres->ai_socktype,
dres->ai_protocol)) < 0)
disorder_fatal(errno, "error creating RTP transmission socket");
- } else { /* request mode slightly different */
- if((rtp_fd = socket(AF_INET,
- SOCK_DGRAM,
- IPPROTO_UDP)) < 0)
- disorder_fatal(errno, "error creating v4 RTP transmission socket");
- if((rtp_fd6 = socket(AF_INET6,
- SOCK_DGRAM,
- IPPROTO_UDP)) < 0)
- disorder_fatal(errno, "error creating v6 RTP transmission socket");
}
+ if((rtp_fd4 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ disorder_fatal(errno, "error creating v4 RTP transmission socket");
+ if((rtp_fd6 = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ disorder_fatal(errno, "error creating v6 RTP transmission socket");
/* Configure the socket according to the desired mode */
switch(rtp_mode) {
case RTP_MULTICAST: {
break;
}
}
- /* Enlarge the socket buffer */
- len = sizeof sndbuf;
- if(getsockopt(rtp_fd, SOL_SOCKET, SO_SNDBUF,
- &sndbuf, &len) < 0)
- disorder_fatal(errno, "error getting SO_SNDBUF");
- if(target_sndbuf > sndbuf) {
- if(setsockopt(rtp_fd, SOL_SOCKET, SO_SNDBUF,
- &target_sndbuf, sizeof target_sndbuf) < 0)
- disorder_error(errno, "error setting SO_SNDBUF to %d", target_sndbuf);
- else
- disorder_info("changed socket send buffer size from %d to %d",
- sndbuf, target_sndbuf);
- } else
- disorder_info("default socket send buffer is %d", sndbuf);
+ /* Enlarge the socket buffers */
+ if (rtp_fd != -1) hack_send_buffer_size(rtp_fd, "master socket");
+ hack_send_buffer_size(rtp_fd4, "IPv4 on-demand socket");
+ hack_send_buffer_size(rtp_fd6, "IPv6 on-demand socket");
/* We might well want to set additional broadcast- or multicast-related
* options here */
if(rtp_mode != RTP_REQUEST) {
static void rtp_stop(void) {
uaudio_thread_stop();
- close(rtp_fd);
- rtp_fd = -1;
- if(rtp_fd6 >= 0) {
- close(rtp_fd6);
- rtp_fd6 = -1;
- }
+ if(rtp_fd >= 0) { close(rtp_fd); rtp_fd = -1; }
+ if(rtp_fd4 >= 0) { close(rtp_fd4); rtp_fd4 = -1; }
+ if(rtp_fd6 >= 0) { close(rtp_fd6); rtp_fd6 = -1; }
}
static void rtp_configure(void) {
char buffer[64];
+ uaudio_set("rtp-mode", config->rtp_mode);
rtp_set_netconfig("rtp-destination-af",
"rtp-destination",
"rtp-destination-port", &config->broadcast);
rc = -1;
else {
r = xmalloc(sizeof *r);
- memcpy(&r->sa, sa, sizeof sa);
+ memcpy(&r->sa, sa, sizeof *sa);
r->next = rtp_recipient_list;
rtp_recipient_list = r;
rc = 0;