implement (probably working) multicast
authormichael <michael>
Sat, 1 Jul 2006 18:07:29 +0000 (18:07 +0000)
committermichael <michael>
Sat, 1 Jul 2006 18:07:29 +0000 (18:07 +0000)
common.c
common.h
http.c
mcast.c
record-dvb.c

index 97ec8073e93d681e7101abf6669f9dbb5af0a331..80327f5292ed0b711fefa261e485309087810916 100644 (file)
--- a/common.c
+++ b/common.c
@@ -2,6 +2,9 @@
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
 
 #include "common.h"
 
 
 #include "common.h"
 
@@ -62,3 +65,28 @@ struct dvb_host *parse(char *urlpart, char *defport)
 
        return dvbhost;
 }
 
        return dvbhost;
 }
+
+int resolve(struct dvb_host *dvbhost, struct sockaddr_in *server)
+{
+       struct addrinfo *s_addrinfo, addrhints;
+       int res;
+
+       bzero(&addrhints, sizeof(struct addrinfo));
+       addrhints.ai_family = PF_INET;
+       addrhints.ai_socktype = dvbhost->socktype;
+
+       if ((res = getaddrinfo(dvbhost->hostname, dvbhost->port, &addrhints, &s_addrinfo))) {
+               fprintf(stderr,"getaddrinfo: %s\n",gai_strerror(res));
+               return -1;
+       }
+
+       bzero(server, sizeof(struct sockaddr_in));
+       server->sin_family = AF_INET;
+       server->sin_addr.s_addr = ((struct sockaddr_in*)(s_addrinfo->ai_addr))->sin_addr.s_addr;
+       server->sin_port = ((struct sockaddr_in*)(s_addrinfo->ai_addr))->sin_port;
+
+       freeaddrinfo(s_addrinfo);
+
+       return 0;
+}
+
index 5f7b1f83bdd85f8b65cfd062f71b09b4b705796b..b7015da22da6c98ab8db2840964b1f69112f5ae3 100644 (file)
--- a/common.h
+++ b/common.h
@@ -2,6 +2,8 @@ struct dvb_host {
        char *hostname;
        char *port;
        char *location;
        char *hostname;
        char *port;
        char *location;
+       int socktype;
 };
 
 struct dvb_host *parse(char *urlpart, char *defport);
 };
 
 struct dvb_host *parse(char *urlpart, char *defport);
+int resolve(struct dvb_host *dvbhost, struct sockaddr_in *server);
diff --git a/http.c b/http.c
index 65c12382c09e49341cbbe887e5772ef7f3502d6e..ca756bd5a56cfa57897d047db6d4d934b2e28dec 100644 (file)
--- a/http.c
+++ b/http.c
@@ -6,7 +6,6 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <netdb.h>
 
 #include "common.h"
 #include "http.h"
 
 #include "common.h"
 #include "http.h"
@@ -28,22 +27,19 @@ int open_http(char *url)
 {
        int fd;
        struct sockaddr_in server;
 {
        int fd;
        struct sockaddr_in server;
-       struct dvb_host *dvbhost;
-       struct addrinfo *s_addrinfo, addrhints;
+       static struct dvb_host *dvbhost = NULL;
        char buffer[BUFFSIZE];
        int i;
 
        if(!is_http(url))
                return -1;
 
        char buffer[BUFFSIZE];
        int i;
 
        if(!is_http(url))
                return -1;
 
-       dvbhost = parse(&(url[7]), "80");
-
-       bzero(&addrhints, sizeof(struct addrinfo));
-       addrhints.ai_family = PF_INET;
-       addrhints.ai_socktype = SOCK_STREAM;
+       if (!dvbhost) {
+               dvbhost = parse(&(url[7]), "80");
+               dvbhost->socktype = SOCK_STREAM;
+       }
 
 
-       if ((i = getaddrinfo(dvbhost->hostname, dvbhost->port, &addrhints, &s_addrinfo))) {
-               fprintf(stderr,"getaddrinfo: %s\n",gai_strerror(i));
+       if (resolve(dvbhost, &server) < 0) {
                return -1;
        }
 
                return -1;
        }
 
@@ -52,19 +48,11 @@ int open_http(char *url)
                return -1;
        }
 
                return -1;
        }
 
-       bzero(&server, sizeof(struct sockaddr_in));
-       server.sin_family = AF_INET;
-       server.sin_addr.s_addr = ((struct sockaddr_in*)(s_addrinfo->ai_addr))->sin_addr.s_addr;
-       server.sin_port = ((struct sockaddr_in*)(s_addrinfo->ai_addr))->sin_port;
-
        if (connect(fd, (struct sockaddr*) &server, sizeof(server)) < 0) {
                perror("connect");
                return -1;
        }
 
        if (connect(fd, (struct sockaddr*) &server, sizeof(server)) < 0) {
                perror("connect");
                return -1;
        }
 
-       freeaddrinfo(s_addrinfo);
-
-
        snprintf(buffer, BUFFSIZE-1, "GET /%s HTTP/1.0\n\n",dvbhost->location);
        buffer[BUFFSIZE-1] = 0;
        send(fd, buffer, strlen(buffer), 0);
        snprintf(buffer, BUFFSIZE-1, "GET /%s HTTP/1.0\n\n",dvbhost->location);
        buffer[BUFFSIZE-1] = 0;
        send(fd, buffer, strlen(buffer), 0);
diff --git a/mcast.c b/mcast.c
index e328932934bcc9c5de30eb765ee13152f7e1d112..5f7dadc5d66bbbea98ef1a733e8695ebababb805 100644 (file)
--- a/mcast.c
+++ b/mcast.c
@@ -2,6 +2,9 @@
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
 
 #include "common.h"
 #include "mcast.h"
 
 #include "common.h"
 #include "mcast.h"
@@ -19,16 +22,41 @@ int is_mcast(char *url)
 
 int open_mcast(char *url)
 {
 
 int open_mcast(char *url)
 {
-       struct dvb_host *dvbhost;
+       static struct dvb_host *dvbhost = NULL;
+       struct sockaddr_in server;
+       struct ip_mreq mreq;
        int fd;
 
        if(!is_mcast(url))
                return -1;
 
        int fd;
 
        if(!is_mcast(url))
                return -1;
 
-       dvbhost = parse(&(url[6]), "2000");
+       if (!dvbhost) {
+               dvbhost = parse(&(url[6]), "2000");
+               dvbhost->socktype = SOCK_DGRAM;
+       }
 
 
-       fprintf(stderr,"multicast currently unimplemented!\n");
-       return -1;
+       if (resolve(dvbhost, &server) < 0) {
+               return -1;
+       }
+
+       bzero(&mreq, sizeof(mreq));
+       mreq.imr_multiaddr = server.sin_addr;
+       mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+
+       if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+               perror("socket");
+               return -1;
+       }
+
+       if (bind(fd, (struct sockaddr*)&server, sizeof(server)) < 0) {
+               perror("bind");
+               return -1;
+       }
+
+       if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
+               perror("setsockopt");
+               return -1;
+       }
 
        return fd;
 }
 
        return fd;
 }
index d32eba1fe0576d63a75f9c5328d6c85d7b01703b..b27ce74908192e938cf574bd2bce0c8d6cc211ec 100644 (file)
@@ -40,7 +40,8 @@ void record(int(*open_fn)(char *), char *url, char *outfile, int duration)
        do {
                if ((bytes = recv(in, buffer, CHUNKSIZE, 0)) < 1) {
                        /* TODO: Insert better connection-loss recovery here */
        do {
                if ((bytes = recv(in, buffer, CHUNKSIZE, 0)) < 1) {
                        /* TODO: Insert better connection-loss recovery here */
-                       in = (*open_fn)(url);
+                       if ((in = (*open_fn)(url)) < 0)
+                               sleep(1);
                }
                written = 0;
                do {
                }
                written = 0;
                do {
Impressum, Datenschutz