aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2014-03-11 00:01:11 +0100
committerHarald Welte <laforge@gnumonks.org>2014-03-11 11:14:37 +0100
commit48f251ab70ea93ec90ce47ce185905e9baea3e12 (patch)
tree0517b538c7d1cf179ee1736a5f16c571f5f2f072
parent156527e11ed2e8b92215027a44eedd9ad2fe85f4 (diff)
socket.c: Work on systems withou netdb.h or ifaddrs.h
... such as Nuttx.
-rw-r--r--configure.ac3
-rw-r--r--src/socket.c79
2 files changed, 79 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index fbc83f39..2ef358e5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -31,7 +31,8 @@ AC_SUBST(LTLDFLAGS_OSMOGSM)
dnl checks for header files
AC_HEADER_STDC
-AC_CHECK_HEADERS(execinfo.h sys/select.h sys/socket.h syslog.h ctype.h)
+AC_CHECK_HEADERS(execinfo.h sys/select.h sys/socket.h syslog.h ctype.h \
+ netdb.h ifaddrs.h)
# for src/conv.c
AC_FUNC_ALLOCA
AC_SEARCH_LIBS([dlopen], [dl dld], [LIBRARY_DL="$LIBS";LIBS=""])
diff --git a/src/socket.c b/src/socket.c
index 6ff00f0d..572c4d1b 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -25,8 +25,10 @@
#include <stdint.h>
#include <string.h>
#include <errno.h>
+#include <fcntl.h>
+
+#ifdef HAVE_NETDB_H
#include <netdb.h>
-#include <ifaddrs.h>
/*! \brief Initialize a socket (including bind/connect)
* \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC
@@ -85,7 +87,12 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto,
if (sfd == -1)
continue;
if (flags & OSMO_SOCK_F_NONBLOCK) {
- if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) {
+#ifdef FIONBIO
+ rc = ioctl(sfd, FIONBIO, (unsigned char *)&on);
+#else
+ rc = fcntl(sfd, F_SETFL, O_NONBLOCK);
+#endif
+ if (rc < 0) {
perror("cannot set this socket unblocking");
close(sfd);
return -EINVAL;
@@ -127,6 +134,69 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto,
}
return sfd;
}
+#else /* HAVE_NETDB_H */
+int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto,
+ const char *host, uint16_t port, unsigned int flags)
+{
+ int sfd, rc, on = 1;
+ struct sockaddr_in sin;
+
+ memset(&sin, 0, sizeof(sin));
+ inet_aton(host, &sin.sin_addr);
+ sin.sin_port = htons(port);
+
+ sfd = socket(family, type, proto);
+ if (sfd == -1)
+ return -EIO;
+
+ if (flags & OSMO_SOCK_F_NONBLOCK) {
+#ifdef FIONBIO
+ rc = ioctl(sfd, FIONBIO, (unsigned char *)&on);
+#else
+ rc = fcntl(sfd, F_SETFL, O_NONBLOCK);
+#endif
+ if (rc < 0) {
+ perror("cannot set this socket unblocking");
+ close(sfd);
+ return -EINVAL;
+ }
+ }
+ if (flags & OSMO_SOCK_F_CONNECT) {
+ rc = connect(sfd, (struct sockaddr *)&sin, sizeof(sin));
+ if (rc == -1 || (rc != -1 && errno == EINPROGRESS)) {
+ close(sfd);
+ return rc;
+ }
+ } else {
+ rc = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR,
+ &on, sizeof(on));
+ if (rc < 0) {
+ perror("cannot setsockopt socket");
+ close(sfd);
+ return rc;
+ }
+ rc = bind(sfd, &sin, sizeof(sin));
+ if (rc < 0) {
+ close(sfd);
+ return rc;
+ }
+ }
+
+ setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
+ /* Make sure to call 'listen' on a bound, connection-oriented sock */
+ if (flags & OSMO_SOCK_F_BIND) {
+ switch (type) {
+ case SOCK_STREAM:
+ case SOCK_SEQPACKET:
+ listen(sfd, 10);
+ break;
+ }
+ }
+ return sfd;
+}
+#endif /* HAVE_NETDB_H */
+
/*! \brief Initialize a socket and fill \ref osmo_fd
* \param[out] ofd file descriptor (will be filled in)
@@ -161,6 +231,7 @@ int osmo_sock_init_ofd(struct osmo_fd *ofd, int family, int type, int proto,
return sfd;
}
+#ifdef HAVE_NETDB_H
/*! \brief Initialize a socket and fill \ref sockaddr
* \param[out] ss socket address (will be filled in)
* \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM
@@ -204,6 +275,7 @@ int osmo_sock_init_sa(struct sockaddr *ss, uint16_t type,
return osmo_sock_init(ss->sa_family, type, proto, host, port, flags);
}
+#endif /* HAVE_NETDB_H */
static int sockaddr_equal(const struct sockaddr *a,
const struct sockaddr *b, unsigned int len)
@@ -233,6 +305,8 @@ static int sockaddr_equal(const struct sockaddr *a,
return 0;
}
+#ifdef HAVE_IFADDRS_H
+#include <ifaddrs.h>
/*! \brief Determine if the given address is a local address
* \param[in] addr Socket Address
* \param[in] addrlen Length of socket address in bytes
@@ -256,6 +330,7 @@ int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen)
return 0;
}
+#endif /* HAVE_IFADDRS_H */
#endif /* HAVE_SYS_SOCKET_H */