From 435a0a5a3bc8114991650a78e1f90049d2f3f343 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 23 Mar 2009 09:16:18 +0100 Subject: socket_wrapper: fix connect() for dgram sockets, if the destination isn't there yet Now we defer the real_connect() for dgram sockets to the first send()/sendto() call, as the destination might not be there at connect time. Commit 66dc53ee017d74a6f610bbe04337f064901fe2a1 was an incomplete fix for this problem. metze --- lib/socket_wrapper/socket_wrapper.c | 56 ++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c index 44082e78a1..553827b192 100644 --- a/lib/socket_wrapper/socket_wrapper.c +++ b/lib/socket_wrapper/socket_wrapper.c @@ -218,6 +218,7 @@ struct socket_info int bcast; int is_server; int connected; + int defer_connect; char *path; char *tmp_path; @@ -1686,10 +1687,15 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL); if (ret == -1) return -1; - swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); + if (si->type == SOCK_DGRAM) { + si->defer_connect = 1; + ret = 0; + } else { + swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); - ret = real_connect(s, (struct sockaddr *)&un_addr, - sizeof(struct sockaddr_un)); + ret = real_connect(s, (struct sockaddr *)&un_addr, + sizeof(struct sockaddr_un)); + } /* to give better errors */ if (ret == -1 && errno == ENOENT) { @@ -1917,7 +1923,22 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con return len; } - + + if (si->defer_connect) { + ret = real_connect(s, (struct sockaddr *)&un_addr, + sizeof(un_addr)); + + /* to give better errors */ + if (ret == -1 && errno == ENOENT) { + errno = EHOSTUNREACH; + } + + if (ret == -1) { + return ret; + } + si->defer_connect = 0; + } + ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); break; default: @@ -2002,6 +2023,33 @@ _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags) len = MIN(len, 1500); + if (si->defer_connect) { + struct sockaddr_un un_addr; + int bcast = 0; + + if (si->bound == 0) { + ret = swrap_auto_bind(si, si->family); + if (ret == -1) return -1; + } + + ret = sockaddr_convert_to_un(si, si->peername, si->peername_len, + &un_addr, 0, &bcast); + if (ret == -1) return -1; + + ret = real_connect(s, (struct sockaddr *)&un_addr, + sizeof(un_addr)); + + /* to give better errors */ + if (ret == -1 && errno == ENOENT) { + errno = EHOSTUNREACH; + } + + if (ret == -1) { + return ret; + } + si->defer_connect = 0; + } + ret = real_send(s, buf, len, flags); if (ret == -1) { -- cgit From 33d9f46674a270a0715213c17581deef192826e1 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 23 Mar 2009 17:36:46 +0100 Subject: libreplace: use libreplace_SAVE_CPPFLAGS instead of SAVE_CPPFLAGS This fixes Samba3's double listing of -I options in CFLAGS, since samba3's configure wraps the call to AC_LIBREPLACE_NETWORK_CHECKS into a SAVE_CPPFLAGS="${CPPFLAGS}" .. CPPFLAGS="${SAVE_CPPFLAGS}" sequence... :-) Michael --- lib/replace/libreplace_network.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/replace/libreplace_network.m4 b/lib/replace/libreplace_network.m4 index 3bac72d136..2af02312ab 100644 --- a/lib/replace/libreplace_network.m4 +++ b/lib/replace/libreplace_network.m4 @@ -170,7 +170,7 @@ fi # The following tests need LIBS="${LIBREPLACE_NETWORK_LIBS}" old_LIBS=$LIBS LIBS="${LIBREPLACE_NETWORK_LIBS}" -SAVE_CPPFLAGS="$CPPFLAGS" +libreplace_SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I$libreplacedir" AC_CHECK_FUNCS(socketpair,[],[LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} socketpair.o"]) @@ -381,7 +381,7 @@ if test x"$libreplace_cv_HAVE_IPV6" = x"yes"; then fi LIBS=$old_LIBS -CPPFLAGS="$SAVE_CPPFLAGS" +CPPFLAGS="$libreplace_SAVE_CPPFLAGS" LIBREPLACEOBJ="${LIBREPLACEOBJ} ${LIBREPLACE_NETWORK_OBJS}" -- cgit