From 706b067f6d89b74054a4fb804a63803dfbd04140 Mon Sep 17 00:00:00 2001 From: ianmdlvl Date: Sun, 15 May 2005 20:27:39 +0000 Subject: [PATCH 1/1] mcastsoundd wip --- cprogs/mcastsoundd.c | 120 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 99 insertions(+), 21 deletions(-) diff --git a/cprogs/mcastsoundd.c b/cprogs/mcastsoundd.c index 499bae4..8a8c670 100644 --- a/cprogs/mcastsoundd.c +++ b/cprogs/mcastsoundd.c @@ -16,20 +16,41 @@ #include #include +#include "myopt.h" + typedef unsigned char Byte; +static int ov_mode= 'r'; +static const char *ov_requ= "127.0.0.1"; static const char *ov_mcast= "239.193.27.221"; + +static int ov_port_requ= 4101; static int ov_port_ctrl= 4101; static int ov_port_data= -1; -static int mcast_fd; -static struct sockaddr_in mcast_sa; +static const struct cmdinfo cmdinfos[]= { + { "server", 0, &ov_mode,0,0, 's' }, + { "player", 0, &ov_mode,0,0, 'p' }, + { "request", 0, &ov_mode,0,0, 'r' }, + { "mcast-addr", 1, 0,&ov_mcast }, + { "requ-addr", 1, 0,&ov_requ }, + { "requ-port", 1, &ov_port_requ }, + { "ctrl-port", 1, &ov_port_ctrl }, + { "data-port", 1, &ov_port_data }, + 0 +}; + + +static int mcast_fd, requ_fd; +static struct sockaddr_in requ_sa, ctrl_sa, data_sa; static void sysfail(const char *m) { perror(m); exit(16); } static Byte packet[1024]; static int packet_len; +/*---------- marshalling ----------*/ + static uint64_t htonll(uint64_t v) { #if LITTLE_ENDIAN return (v >> 32) | (v << 32); @@ -129,6 +150,8 @@ MARS #undef FR0 #undef MAR +/*---------- general stuff ----------*/ + static void nonblock(int fd) { int r; r= fcntl(fd,F_GETFL); if (r<0) sysfail("nonblock fcntl F_GETFL"); @@ -146,12 +169,40 @@ static void blocksignals(int how) { if (r) sysfail("sigprocmask"); } +static int mksocket(int type, int proto, + const struct sockaddr_in *sa, const char *what) { + int fd, r; + + fd= socket(PF_INET, type, proto); + if (fd<0) sysfail("socket %s",what); + + r= bind(fd, (struct sockaddr*)&mcast_sa, sizeof(*sa)); + if (r) sysfail("bind %s",what); + + return fd; +} + +static void mkmcastrecv(const struct sockaddr_in *sa, const char *what) { + struct ip_mreq mreq; + int r; + + mcast_fd= mksocket(SOCK_DGRAM, IPPROTO_UDP, sa, what); + + mreq.imr_multiaddr= sa->sin_addr; + mreq.imr_interface.s_addr= INADDR_ANY; + r= setsockopt(mcast_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); + if (r) sysfail("add mcast membership %s", what); +} + +/*---------- player ----------*/ + static void recvd_play(void) { Mar_CTRL_PLAY pkt; int r; r= unmar_CTRL_PLAY(&pkt); if (r) { fprintf(stderr,"bad PLAY packet\n"); return; } + } static void recvd_stop(void) { @@ -165,23 +216,11 @@ static void recvd_stop(void) { static void player(void) { struct sockaddr_in peer_sa, old_peer_sa; socklen_t peer_salen; - struct ip_mreq mreq; int r; - - memset(&old_peer_sa, 0, sizeof(old_peer_sa)); - - mcast_fd= socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (mcast_fd<0) sysfail("mcast_fd socket"); - - r= bind(mcast_fd, (struct sockaddr*)&mcast_sa, sizeof(mcast_sa)); - if (r) sysfail("mcast_fd bind"); - mcast_sa.sin_port= htons(ov_port_ctrl); + mkmcastrecv(&ctrl_sa, "ctrl"); - mreq.imr_multiaddr= mcast_sa.sin_addr; - mreq.imr_interface.s_addr= INADDR_ANY; - r= setsockopt(mcast_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); - if (r) sysfail("mcast_fd add memb"); + memset(&old_peer_sa, 0, sizeof(old_peer_sa)); for (;;) { peer_salen= sizeof(peer_sa); @@ -229,16 +268,55 @@ static void player(void) { } } -int main(int argc, const char *const *argv) { +/*---------- server ----------*/ + +void server(void) { + requ_fd= mksocket(SOCK_STREAM, IPPROTO_TCP, &requ_sa, "requ"); + + +/*---------- main ----------*/ + +static void argaddr(struct sin_addr *sa, const char *addr_name, int port) { + memset(sa,0,sizeof(*sa)); + sa->sin_family= AF_INET; + + r= inet_aton(ov_mcast, &mcast_sa.sin_addr); + if (!r) badusage("invalid addr `%s'", addr_name); + + if (port<0 || port>65536) badusage("invalid port %d",port); + + sa->sin_port= htons(port); +} + +int main(int argc, const char **argv) { int r; if (ov_port_data < 0) ov_port_data= ov_port_ctrl+1; + myopt(&argv, cmdinfos); + + argaddr(&requ_sa, ov_requ, ov_requ_port); + argaddr(&ctrl_sa, ov_mcast, ov_ctrl_port); + argaddr(&data_sa, ov_data, ov_data_port); - memset(&mcast_sa,0,sizeof(mcast_sa)); - mcast_sa.sin_family= AF_INET; - r= inet_aton(ov_mcast, &mcast_sa.sin_addr); assert(r); + if (argv[1] && ov_mode != 'p') + badusage("mode takes no non-option arguments"); + + switch (ov_mode) { + case 'p': + player(); + break; + case 's': + server(); + break; + case 'r': + if (!argv[1] || argv[2]) + badusage("play-requester takes one non-option argument"); + request(argv[1]); + break; + default: + abort(); + } - player(); nonblock(0); mar_CTRL_PLAY(0); mar_CTRL_STOP(0); -- 2.30.2