#include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
 
 #include "common.h"
 
 
        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;
+}
+
 
        char *hostname;
        char *port;
        char *location;
+       int socktype;
 };
 
 struct dvb_host *parse(char *urlpart, char *defport);
+int resolve(struct dvb_host *dvbhost, struct sockaddr_in *server);
 
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <netdb.h>
 
 #include "common.h"
 #include "http.h"
 {
        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;
 
-       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;
        }
 
-       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;
        }
 
-       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);
 
 #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"
 
 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;
 
-       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;
 }
 
        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 {