#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 {