Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[vdr] Re: Feature request: AF independence for vdr.
On Mon, 5 Apr 2004 18:52:18 +0200
DOm <angelus.dei@tiscalinet.it> wrote:
> Hallo,
>
> i'm studying a little IPv6 and i'll try to port vdr to IPv6 adopting
> an AF (Address family) independent approach as suggested in
> http://www.kame.net/newsletter/19980604/
> any chance to have some help ? I'm not a great programmer :)
>
> Have a good time,
> Angelus.
>
Well, i tried to code a patch to have AF independence and here we are.
I think such an independence could be always a good idea... even if you
hate IPv6 :) I stealed the code from:
http://jungla.dit.upm.es/~ecastro/IPv6-web/ipv6.html and
http://www.ietf.org/internet-drafts/draft-shin-v6ops-application-transition-02.txt
By the way, the patch is highly EXPERIMENTAL, it can break something,
but since i have a dual stack IPv6-IPv4 machine i would like to have
comments _and_ critics by someone with IPv4 only machine (most of you).
The Acceptable Addresses feature (svdrphosts.conf) is disabled in this
patch because i don't know how to parse IPv6 addresses in the correct
way, yet. That is: connections will be accepted from ANY host, sorry.
Many thanks for you tests,
Angelus.
diff -pruN vdr-1.3.6-vanilla/runvdr vdr-1.3.6-AFind/runvdr
--- vdr-1.3.6-vanilla/runvdr 2004-01-09 17:19:26.000000000 +0100
+++ vdr-1.3.6-AFind/runvdr 2004-04-06 17:20:05.000000000 +0200
@@ -24,7 +24,7 @@ DVBDIR="../DVB/driver"
VDRPRG="./vdr"
VDRCMD="$VDRPRG -w 60 $*"
-LSMOD="`/sbin/lsmod | grep -w '^dvb' | wc -l`"
+LSMOD="`/sbin/lsmod | grep ^dvb | wc -l`"
KILL="/usr/bin/killall -q -TERM"
# Load driver if it hasn't been loaded already:
diff -pruN vdr-1.3.6-vanilla/svdrp.c vdr-1.3.6-AFind/svdrp.c
--- vdr-1.3.6-vanilla/svdrp.c 2004-02-24 13:24:43.000000000 +0100
+++ vdr-1.3.6-AFind/svdrp.c 2004-04-06 18:12:57.000000000 +0200
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
+#include <netdb.h>
#include <sys/time.h>
#include <unistd.h>
#include "channels.h"
@@ -61,42 +62,78 @@ void cSocket::Close(void)
bool cSocket::Open(void)
{
if (sock < 0) {
- // create socket:
- sock = socket(PF_INET, SOCK_STREAM, 0);
+ struct addrinfo hints, *res, *ressave;
+ int error;
+
+ memset(&hints, 0, sizeof(hints));
+
+ /*
+ AI_PASSIVE flag: the resulting address is used to bind
+ to a socket for accepting incoming connections.
+ So, when the hostname==NULL, getaddrinfo function will
+ return one entry per allowed protocol family containing
+ the unspecified address for that family.
+ */
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ // 5 = strlen("65535") the highest possible port number
+ char service[5];
+ snprintf(service, 5, "%d", port);
+ error = getaddrinfo(NULL, service, &hints, &res);
+ if (error != 0) {
+ // handle getaddrinfo error
+ esyslog("Error in getaddrinfo.");
+ return false;
+ }
+
+ ressave=res;
+
+ /*
+ Try open socket with each address getaddrinfo returned,
+ until getting a valid listening socket.
+ */
+ while (res) {
+ // create socket:
+ sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (!(sock < 0)) {
+ // allow it to always reuse the same port:
+ int ReUseAddr = 1;
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &ReUseAddr, sizeof(ReUseAddr));
+ // make it non-blocking:
+ int oldflags = fcntl(sock, F_GETFL, 0);
+ if (oldflags < 0) {
+ LOG_ERROR;
+ return false;
+ }
+ oldflags |= O_NONBLOCK;
+ if (fcntl(sock, F_SETFL, oldflags) < 0) {
+ LOG_ERROR;
+ return false;
+ }
+ if (bind(sock, res->ai_addr, res->ai_addrlen) == 0)
+ break;
+
+ LOG_ERROR;
+ close(sock);
+ sock=-1;
+ }
+ res = res->ai_next;
+ }
if (sock < 0) {
LOG_ERROR;
port = 0;
+ freeaddrinfo(ressave);
return false;
- }
- // allow it to always reuse the same port:
- int ReUseAddr = 1;
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &ReUseAddr, sizeof(ReUseAddr));
- //
- struct sockaddr_in name;
- name.sin_family = AF_INET;
- name.sin_port = htons(port);
- name.sin_addr.s_addr = htonl(INADDR_ANY);
- if (bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0) {
- LOG_ERROR;
- Close();
- return false;
- }
- // make it non-blocking:
- int oldflags = fcntl(sock, F_GETFL, 0);
- if (oldflags < 0) {
- LOG_ERROR;
- return false;
- }
- oldflags |= O_NONBLOCK;
- if (fcntl(sock, F_SETFL, oldflags) < 0) {
- LOG_ERROR;
- return false;
- }
+ }
+
// listen to the socket:
if (listen(sock, queue) < 0) {
LOG_ERROR;
return false;
}
+ freeaddrinfo(ressave);
}
return true;
}
@@ -104,18 +141,28 @@ bool cSocket::Open(void)
int cSocket::Accept(void)
{
if (Open()) {
- struct sockaddr_in clientname;
- uint size = sizeof(clientname);
- int newsock = accept(sock, (struct sockaddr *)&clientname, &size);
+ struct sockaddr_storage clientname;
+ socklen_t addrlen = sizeof(clientname);
+ int newsock = accept(sock, (struct sockaddr *)&clientname, &addrlen);
if (newsock > 0) {
- bool accepted = SVDRPhosts.Acceptable(clientname.sin_addr.s_addr);
+ //bool accepted = SVDRPhosts.Acceptable(clientname.sin_addr.s_addr);
+ bool accepted = true;
if (!accepted) {
const char *s = "Access denied!\n";
write(newsock, s, strlen(s));
close(newsock);
newsock = -1;
}
- isyslog("connect from %s, port %hd - %s", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port), accepted ? "accepted" : "DENIED");
+
+ char clienthost[NI_MAXHOST];
+ char clientservice[NI_MAXSERV];
+ memset(clienthost, 0, sizeof(clienthost));
+ memset(clientservice, 0, sizeof(clientservice));
+ getnameinfo((struct sockaddr *)&clientname, addrlen,
+ clienthost, sizeof(clienthost),
+ clientservice, sizeof(clientservice),
+ NI_NUMERICHOST);
+ isyslog("connect from %s, port %s - %s", clienthost, clientservice, accepted ? "accepted" : "DENIED");
}
else if (errno != EINTR && errno != EAGAIN)
LOG_ERROR;
Home |
Main Index |
Thread Index