On Mon, Jan 14, 2013 at 12:25:37AM +0100, Pablo Neira Ayuso wrote:
> On Sun, Jan 13, 2013 at 01:24:13AM +0100, Holger Hans Peter Freyther wrote:
> > On Sun, Jan 13, 2013 at 12:30:33AM +0100, Pablo Neira Ayuso wrote:
> > 
> > > Just filed the bug to glibc, you can track it here:
> > > 
> > > http://sourceware.org/bugzilla/show_bug.cgi?id=15015
> > > 
> > > Sorry for lagging with this.
> > 
> > thanks! any idea of a non ugly work-around. Even if it is glibc bug,
> > and it will be fixed.. RHEL, Debian 6.0 will unlikely patch it.
> 
> Attached a workaround patch. It's a bit of cheating, but it allows us
> to obtain the address information from the kernel, which is what you
> need. As Peter mentioned, let's find a fast path to resolve this until
> some fix lands on glibc.
> 
> Let me know!

Patch was incomplete, sorry. New version attached.
>From e90ae70d81e68646d2246f1ec164cd77655a0b54 Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <[email protected]>
Date: Mon, 14 Jan 2013 00:12:28 +0100
Subject: [PATCH] socket: fix osmo_sock_init with SOCK_RAW and IPPROTO_RAW

getaddrinfo returns EAI_SERVICE (-8) if that combination is used.

More information available in here:

http://sourceware.org/bugzilla/show_bug.cgi?id=15015

Reported by Holger Hans Peter Freyther.

While at it, this patch also removes hints.ai_flags = 0 as memset
to zero already happened just a bit before that.
---
 src/socket.c |   19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/socket.c b/src/socket.c
index 53205cd..a5530d0 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -54,9 +54,16 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto,
 	sprintf(portbuf, "%u", port);
 	memset(&hints, 0, sizeof(struct addrinfo));
 	hints.ai_family = family;
-	hints.ai_socktype = type;
-	hints.ai_flags = 0;
-	hints.ai_protocol = proto;
+	if (type == SOCK_RAW) {
+		/* Workaround for glibc, that returns EAI_SERVICE (-8) if
+		 * SOCK_RAW and IPPROTO_GRE is used.
+		 */
+		hints.ai_socktype = SOCK_DGRAM;
+		hints.ai_protocol = IPPROTO_UDP;
+	} else {
+		hints.ai_socktype = type;
+		hints.ai_protocol = proto;
+	}
 
 	if (flags & OSMO_SOCK_F_BIND)
 		hints.ai_flags |= AI_PASSIVE;
@@ -68,6 +75,12 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto,
 	}
 
 	for (rp = result; rp != NULL; rp = rp->ai_next) {
+		/* Workaround for glibc again */
+		if (type == SOCK_RAW) {
+			rp->ai_socktype = SOCK_RAW;
+			rp->ai_protocol = proto;
+		}
+
 		sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
 		if (sfd == -1)
 			continue;
-- 
1.7.10.4

Reply via email to