can be enabled on the buildfarm without requiring --enable-developer
- Support tcp and udp being used on the same port
- FIx some portability issues (should fix the build on
some hosts on the buildfarm)
- Ignore setting TCP_NODELAY on (semi-)TCP sockets rather then complain about
it not being supported (saves us from a couple of error messages for each
connection that is opened)
(This used to be commit
443fb7853b8d3cb516c442fdc595038544b75738)
SMB_INCLUDE_M4(scripting/config.m4)
SMB_INCLUDE_M4(gtk/config.m4)
SMB_INCLUDE_M4(ntvfs/posix/config.m4)
SMB_INCLUDE_M4(scripting/config.m4)
SMB_INCLUDE_M4(gtk/config.m4)
SMB_INCLUDE_M4(ntvfs/posix/config.m4)
+SMB_INCLUDE_M4(lib/socket_wrapper/config.m4)
ALLLIBS_LIBS="$LIBS"
ALLLIBS_CFLAGS="$CFLAGS"
ALLLIBS_LIBS="$LIBS"
ALLLIBS_CFLAGS="$CFLAGS"
#include <net/if.h>
#endif
#include <net/if.h>
#endif
#define SOCKET_WRAPPER_REPLACE
#include "lib/socket_wrapper/socket_wrapper.h"
#endif
#define SOCKET_WRAPPER_REPLACE
#include "lib/socket_wrapper/socket_wrapper.h"
#endif
--- /dev/null
+AC_ARG_ENABLE(socket-wrapper,
+[ --enable-socket-wrapper Turn on socket wrapper library (default=no)],
+ [if eval "test x$enable_socket_wrapper = xyes"; then
+ AC_DEFINE(SOCKET_WRAPPER,1,[Use socket wrapper library])
+ fi])
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifdef SAMBA_MAJOR_VERSION
#include "includes.h"
#include "system/network.h"
#else
#include "includes.h"
#include "system/network.h"
#else
#include <errno.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <errno.h>
#include <sys/un.h>
#include <netinet/in.h>
+#include <netinet/tcp.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define real_close close
#endif
#define real_close close
#endif
-static struct sockaddr *memdup(const void *data, socklen_t len)
+static struct sockaddr *sockaddr_dup(const void *data, socklen_t len)
{
struct sockaddr *ret = (struct sockaddr *)malloc(len);
memcpy(ret, data, len);
{
struct sockaddr *ret = (struct sockaddr *)malloc(len);
memcpy(ret, data, len);
{
unsigned int prt;
const char *p;
{
unsigned int prt;
const char *p;
if ((*len) < sizeof(struct sockaddr_in)) {
return 0;
if ((*len) < sizeof(struct sockaddr_in)) {
return 0;
p = strchr(un->sun_path, '/');
if (p) p++; else p = un->sun_path;
p = strchr(un->sun_path, '/');
if (p) p++; else p = un->sun_path;
- if(sscanf(p, "sock_ip_%u", &prt) == 1)
+ if(sscanf(p, "sock_ip_%d_%u", &type, &prt) == 1)
{
in->sin_port = htons(prt);
}
{
in->sin_port = htons(prt);
}
-static int convert_in_un(const struct sockaddr_in *in, struct sockaddr_un *un)
+static int convert_in_un(int type, const struct sockaddr_in *in, struct sockaddr_un *un)
{
uint16_t prt = ntohs(in->sin_port);
/* FIXME: ENETUNREACH if in->sin_addr is not loopback */
{
uint16_t prt = ntohs(in->sin_port);
/* FIXME: ENETUNREACH if in->sin_addr is not loopback */
- un->sun_family = AF_LOCAL;
- snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%u", getenv("SOCKET_WRAPPER_DIR"), prt);
+ snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%d_%u", getenv("SOCKET_WRAPPER_DIR"), type, prt);
-static int sockaddr_convert_to_un(const struct sockaddr *in_addr, socklen_t in_len,
+static int sockaddr_convert_to_un(const struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len,
struct sockaddr_un *out_addr)
{
if (!out_addr)
return 0;
struct sockaddr_un *out_addr)
{
if (!out_addr)
return 0;
+ out_addr->sun_family = AF_LOCAL;
+
switch (in_addr->sa_family) {
case AF_INET:
switch (in_addr->sa_family) {
case AF_INET:
- return convert_in_un((const struct sockaddr_in *)in_addr, out_addr);
+ return convert_in_un(si->type, (const struct sockaddr_in *)in_addr, out_addr);
case AF_LOCAL:
memcpy(out_addr, in_addr, sizeof(*out_addr));
return 0;
case AF_LOCAL:
memcpy(out_addr, in_addr, sizeof(*out_addr));
return 0;
-static int sockaddr_convert_from_un(const struct sockaddr_un *in_addr,
+static int sockaddr_convert_from_un(const struct socket_info *si,
+ const struct sockaddr_un *in_addr,
int family,
struct sockaddr *out_addr,
socklen_t *out_len)
int family,
struct sockaddr *out_addr,
socklen_t *out_len)
- ret = sockaddr_convert_from_un(&un_addr, parent_si->domain, addr, addrlen);
+ ret = sockaddr_convert_from_un(parent_si, &un_addr, parent_si->domain, addr, addrlen);
if (addr && addrlen) {
child_si->myname_len = *addrlen;
if (addr && addrlen) {
child_si->myname_len = *addrlen;
- child_si->myname = memdup(addr, *addrlen);
+ child_si->myname = sockaddr_dup(addr, *addrlen);
return real_connect(s, serv_addr, addrlen);
}
return real_connect(s, serv_addr, addrlen);
}
- ret = sockaddr_convert_to_un((const struct sockaddr *)serv_addr, addrlen, &un_addr);
+ ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr);
if (ret < 0) return ret;
ret = real_connect(s,
if (ret < 0) return ret;
ret = real_connect(s,
if (ret >= 0) {
si->peername_len = addrlen;
if (ret >= 0) {
si->peername_len = addrlen;
- si->peername = memdup(serv_addr, addrlen);
+ si->peername = sockaddr_dup(serv_addr, addrlen);
return real_bind(s, myaddr, addrlen);
}
return real_bind(s, myaddr, addrlen);
}
- ret = sockaddr_convert_to_un((const struct sockaddr *)myaddr, addrlen, &un_addr);
+ ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr);
if (ret < 0) return ret;
unlink(un_addr.sun_path);
if (ret < 0) return ret;
unlink(un_addr.sun_path);
if (ret >= 0) {
si->myname_len = addrlen;
if (ret >= 0) {
si->myname_len = addrlen;
- si->myname = memdup(myaddr, addrlen);
+ si->myname = sockaddr_dup(myaddr, addrlen);
return real_getsockopt(s, level, optname, optval, optlen);
}
return real_getsockopt(s, level, optname, optval, optlen);
}
- if (level != SOL_SOCKET) {
+ if (level == SOL_SOCKET) {
+ return real_getsockopt(s, level, optname, optval, optlen);
+ }
+
+ switch (si->domain) {
+ case AF_LOCAL:
+ return real_getsockopt(s, level, optname, optval, optlen);
+ default:
errno = ENOPROTOOPT;
return -1;
}
errno = ENOPROTOOPT;
return -1;
}
-
- return real_getsockopt(s, level, optname, optval, optlen);
}
int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
}
int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
return real_setsockopt(s, level, optname, optval, optlen);
}
return real_setsockopt(s, level, optname, optval, optlen);
}
- if (level != SOL_SOCKET) {
+ if (level == SOL_SOCKET) {
+ return real_setsockopt(s, level, optname, optval, optlen);
+ }
+
+ switch (si->domain) {
+ case AF_LOCAL:
+ return real_setsockopt(s, level, optname, optval, optlen);
+ case AF_INET:
+ /* Silence some warnings */
+#ifdef TCP_NODELAY
+ if (optname == TCP_NODELAY)
+ return 0;
+#endif
+ default:
errno = ENOPROTOOPT;
return -1;
}
errno = ENOPROTOOPT;
return -1;
}
-
- return real_setsockopt(s, level, optname, optval, optlen);
}
ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
}
ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
- ret = sockaddr_convert_from_un(&un_addr, si->domain, from, fromlen);
+ ret = sockaddr_convert_from_un(si, &un_addr, si->domain, from, fromlen);
return real_sendto(s, buf, len, flags, to, tolen);
}
return real_sendto(s, buf, len, flags, to, tolen);
}
- ret = sockaddr_convert_to_un(to, tolen, &un_addr);
+ ret = sockaddr_convert_to_un(si, to, tolen, &un_addr);