/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
#include <string.h>
#include <poll.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/un.h>
#include <stdio.h>

#include "os/mynewt.h"
#include "mn_socket/mn_socket.h"
#include "mn_socket/mn_socket_ops.h"
#include "native_sockets/native_sock.h"

#include "native_sock_priv.h"

static struct native_sock {
    struct mn_socket ns_sock;
    int ns_fd;
    unsigned int ns_connect:1;  /* Non-blocking connect in progress. */
    unsigned int ns_poll:1;
    unsigned int ns_listen:1;
    uint8_t ns_type;
    uint8_t ns_pf;
    struct os_sem ns_sem;
    STAILQ_HEAD(, os_mbuf_pkthdr) ns_rx;
    struct os_mbuf *ns_tx;
} native_socks[MYNEWT_VAL(NATIVE_SOCKETS_MAX)];

static struct native_sock_state {
    struct pollfd poll_fds[MYNEWT_VAL(NATIVE_SOCKETS_MAX)];
    int poll_fd_cnt;
    struct os_mutex mtx;
    struct os_task task;
} native_sock_state;

static const struct mn_socket_ops native_sock_ops = {
    .mso_create = native_sock_create,
    .mso_close = native_sock_close,

    .mso_bind = native_sock_bind,
    .mso_connect = native_sock_connect,
    .mso_listen = native_sock_listen,

    .mso_sendto = native_sock_sendto,
    .mso_recvfrom = native_sock_recvfrom,

    .mso_getsockopt = native_sock_getsockopt,
    .mso_setsockopt = native_sock_setsockopt,

    .mso_getsockname = native_sock_getsockname,
    .mso_getpeername = native_sock_getpeername,

    .mso_itf_getnext = native_sock_itf_getnext,
    .mso_itf_addr_getnext = native_sock_itf_addr_getnext
};

static struct native_sock *
native_get_sock(void)
{
    int i;
    struct native_sock *ns;

    for (i = 0; i < MYNEWT_VAL(NATIVE_SOCKETS_MAX); i++) {
        if (native_socks[i].ns_fd < 0) {
            ns = &native_socks[i];
            ns->ns_poll = 0;
            ns->ns_listen = 0;
            return ns;
        }
    }
    return NULL;
}

static struct native_sock *
native_find_sock(int fd)
{
    int i;

    for (i = 0; i < MYNEWT_VAL(NATIVE_SOCKETS_MAX); i++) {
        if (native_socks[i].ns_fd == fd) {
            return &native_socks[i];
        }
    }
    return NULL;
}

static void
native_sock_poll_rebuild(struct native_sock_state *nss)
{
    struct native_sock *ns;
    int i;
    int j;

    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
    for (i = 0, j = 0; i < MYNEWT_VAL(NATIVE_SOCKETS_MAX); i++) {
        ns = &native_socks[i];
        if (ns->ns_fd < 0) {
            continue;
        }
        if (!ns->ns_poll) {
            continue;
        }
        nss->poll_fds[j].fd = ns->ns_fd;
        nss->poll_fds[j].events = POLLIN | POLLOUT;
        nss->poll_fds[j].revents = 0;
        j++;
    }
    nss->poll_fd_cnt = j;
    os_mutex_release(&nss->mtx);
}

int
native_sock_err_to_mn_err(int err)
{
    switch (err) {
    case 0:
        return 0;
    case EAGAIN:
    case EINPROGRESS:
        return MN_EAGAIN;
    case ENOTCONN:
        return MN_ENOTCONN;
    case ETIMEDOUT:
        return MN_ETIMEDOUT;
    case ENOMEM:
        return MN_ENOBUFS;
    case EADDRINUSE:
        return MN_EADDRINUSE;
    case EADDRNOTAVAIL:
        return MN_EADDRNOTAVAIL;
    default:
        return MN_EINVAL;
    }
}

static int
native_sock_mn_addr_to_addr(struct mn_sockaddr *ms, struct sockaddr *sa,
  int *sa_len)
{
    struct sockaddr_un *sun = (struct sockaddr_un *)sa;
    struct sockaddr_in *sin = (struct sockaddr_in *)sa;
    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
    struct mn_sockaddr_un *msun = (struct mn_sockaddr_un *)ms;
    struct mn_sockaddr_in *msin = (struct mn_sockaddr_in *)ms;
    struct mn_sockaddr_in6 *msin6 = (struct mn_sockaddr_in6 *)ms;

    switch (ms->msa_family) {
    case MN_AF_INET:
        sin->sin_family = AF_INET;
#ifndef MN_LINUX
        sin->sin_len = sizeof(*sin);
#endif
        sin->sin_addr.s_addr = msin->msin_addr.s_addr;
        sin->sin_port = msin->msin_port;
        *sa_len = sizeof(*sin);
        break;
    case MN_AF_INET6:
        sin6->sin6_family = AF_INET6;
#ifndef MN_LINUX
        sin6->sin6_len = sizeof(*sin6);
#endif
        sin6->sin6_port = msin6->msin6_port;
        sin6->sin6_flowinfo = msin6->msin6_flowinfo;
        memcpy(&sin6->sin6_addr, &msin6->msin6_addr,
               sizeof(msin6->msin6_addr));
        sin6->sin6_scope_id = msin6->msin6_scope_id;
        *sa_len = sizeof(*sin6);
        break;
    case MN_AF_LOCAL:
        sun->sun_family = AF_LOCAL;
#ifndef MN_LINUX
        sun->sun_len = sizeof(*sun);
#endif
        sun->sun_path[0] = '\0';
        strncat(sun->sun_path, msun->msun_path, sizeof sun->sun_path);
        if (strcmp(sun->sun_path, msun->msun_path) != 0) {
            /* Path too long. */
            return MN_EINVAL;
        }
        *sa_len = sizeof(*sun);
        break;
    default:
        return MN_EPROTONOSUPPORT;
    }
    return 0;
}

static int
native_sock_addr_to_mn_addr(struct sockaddr *sa, struct mn_sockaddr *ms)
{
    struct mn_sockaddr_un *msun = (struct mn_sockaddr_un *)ms;
    struct mn_sockaddr_in *msin = (struct mn_sockaddr_in *)ms;
    struct mn_sockaddr_in6 *msin6 = (struct mn_sockaddr_in6 *)ms;
    struct sockaddr_un *sun = (struct sockaddr_un *)sa;
    struct sockaddr_in *sin = (struct sockaddr_in *)sa;
    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;

    switch (sa->sa_family) {
    case AF_INET:
        msin->msin_family = MN_AF_INET;
        msin->msin_len = sizeof(*msin);
        msin->msin_addr.s_addr = sin->sin_addr.s_addr;
        msin->msin_port = sin->sin_port;
        break;
    case AF_INET6:
        msin6->msin6_family = MN_AF_INET6;
        msin6->msin6_len = sizeof(*msin6);
        msin6->msin6_port = sin6->sin6_port;
        msin6->msin6_flowinfo = sin6->sin6_flowinfo;
        memcpy(&msin6->msin6_addr, &sin6->sin6_addr,
               sizeof(msin6->msin6_addr));
        msin6->msin6_scope_id = sin6->sin6_scope_id;
        break;
    case AF_LOCAL:
        msun->msun_family = MN_AF_LOCAL;
        strncpy(msun->msun_path, sun->sun_path, sizeof msun->msun_path);
        if (strcmp(msun->msun_path, sun->sun_path) != 0) {
            /* Path too long. */
            return MN_EINVAL;
        }
        break;
    default:
        return MN_EPROTONOSUPPORT;
    }
    return 0;
}

int
native_sock_create(struct mn_socket **sp, uint8_t domain,
  uint8_t type, uint8_t proto)
{
    struct native_sock_state *nss = &native_sock_state;
    struct native_sock *ns;
    int idx;
    int rc;

    switch (domain) {
    case MN_PF_INET:
        domain = PF_INET;
        break;
    case MN_PF_INET6:
        domain = PF_INET6;
        break;
    case MN_PF_LOCAL:
        domain = PF_LOCAL;
        break;
    default:
        return MN_EPROTONOSUPPORT;
    }

    switch (type) {
    case MN_SOCK_DGRAM:
        type = SOCK_DGRAM;
        break;
    case MN_SOCK_STREAM:
        type = SOCK_STREAM;
        break;
    case 0:
        break;
    default:
        return MN_EPROTONOSUPPORT;
    }

    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
    ns = native_get_sock();
    if (!ns) {
        os_mutex_release(&nss->mtx);
        return MN_ENOBUFS;
    }
    os_sem_init(&ns->ns_sem, 0);
    idx = socket(domain, type, proto);

    /* Make the socket nonblocking. */
    rc = fcntl(idx, F_SETFL, fcntl(idx, F_GETFL, 0) | O_NONBLOCK);
    assert(rc == 0);

    ns->ns_fd = idx;
    ns->ns_pf = domain;
    ns->ns_type = type;
    os_mutex_release(&nss->mtx);
    if (idx < 0) {
        return MN_ENOBUFS;
    }
    *sp = &ns->ns_sock;
    return 0;
}

int
native_sock_close(struct mn_socket *s)
{
    struct native_sock_state *nss = &native_sock_state;
    struct native_sock *ns = (struct native_sock *)s;
    struct os_mbuf_pkthdr *m;

    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
    close(ns->ns_fd);
    ns->ns_fd = -1;

    /*
     * When socket is closed, we must free all mbufs which might be
     * queued in it.
     */
    while ((m = STAILQ_FIRST(&ns->ns_rx))) {
        STAILQ_REMOVE_HEAD(&ns->ns_rx, omp_next);
        os_mbuf_free_chain(OS_MBUF_PKTHDR_TO_MBUF(m));
    }
    os_mbuf_free_chain(ns->ns_tx);
    native_sock_poll_rebuild(nss);
    os_mutex_release(&nss->mtx);
    return 0;
}

int
native_sock_connect(struct mn_socket *s, struct mn_sockaddr *addr)
{
    struct native_sock_state *nss = &native_sock_state;
    struct native_sock *ns = (struct native_sock *)s;
    struct sockaddr_storage ss;
    struct sockaddr *sa = (struct sockaddr *)&ss;
    int rc;
    int sa_len;
    int in_progress = 0;

    rc = native_sock_mn_addr_to_addr(addr, sa, &sa_len);
    if (rc) {
        return rc;
    }
    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
    rc = connect(ns->ns_fd, sa, sa_len);
    if (rc != 0) {
        if (errno == EINPROGRESS) {
            /* Non-blocking connect initiated. */
            in_progress = 1;
            ns->ns_connect = 1;
        } else {
            rc = errno;
            os_mutex_release(&nss->mtx);
            return native_sock_err_to_mn_err(rc);
        }
    }
    ns->ns_poll = 1;
    native_sock_poll_rebuild(nss);
    os_mutex_release(&nss->mtx);

    /* Indicate writability if connection fully established. */
    if (!in_progress) {
        mn_socket_writable(s, 0);
    }

    return 0;
}

int
native_sock_bind(struct mn_socket *s, struct mn_sockaddr *addr)
{
    struct native_sock_state *nss = &native_sock_state;
    struct native_sock *ns = (struct native_sock *)s;
    struct sockaddr_un ss;
    struct sockaddr *sa = (struct sockaddr *)&ss;
    int rc;
    int sa_len;
    int val = 1;

    rc = native_sock_mn_addr_to_addr(addr, sa, &sa_len);
    if (rc) {
        return rc;
    }

    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
    if (ns->ns_type == SOCK_STREAM) {
        rc = setsockopt(ns->ns_fd, SOL_SOCKET, SO_REUSEADDR, &val,
          sizeof(val));
        if (rc) {
            goto err;
        }
    }
    rc = ioctl(ns->ns_fd, FIONBIO, (char *)&val);
    if (rc) {
        goto err;
    }
    if (bind(ns->ns_fd, sa, sa_len)) {
        goto err;
    }
    if (ns->ns_type == SOCK_DGRAM) {
        ns->ns_poll = 1;
        native_sock_poll_rebuild(nss);
    }
    os_mutex_release(&nss->mtx);
    return 0;
err:
    rc = errno;
    os_mutex_release(&nss->mtx);
    return native_sock_err_to_mn_err(rc);
}

int
native_sock_listen(struct mn_socket *s, uint8_t qlen)
{
    struct native_sock_state *nss = &native_sock_state;
    struct native_sock *ns = (struct native_sock *)s;
    int rc;

    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
    if (listen(ns->ns_fd, qlen)) {
        rc = errno;
        os_mutex_release(&nss->mtx);
        return native_sock_err_to_mn_err(rc);
    }
    ns->ns_poll = 1;
    ns->ns_listen = 1;
    native_sock_poll_rebuild(nss);
    os_mutex_release(&nss->mtx);
    return 0;
}

/*
 * TX routine for stream sockets (TCP). The data to send is pointed
 * by ns_tx.
 * Keep sending mbufs until socket says that it can't take anymore.
 * then wait for send event notification before continuing.
 */
static int
native_sock_stream_tx(struct native_sock *ns, int notify)
{
    struct native_sock_state *nss = &native_sock_state;
    struct os_mbuf *m;
    struct os_mbuf *n;
    int rc;

    rc = 0;

    os_mutex_pend(&nss->mtx, OS_TIMEOUT_NEVER);
    while (ns->ns_tx && rc == 0) {
        m = ns->ns_tx;
        n = SLIST_NEXT(m, om_next);

        errno = 0;
        rc = write(ns->ns_fd, m->om_data, m->om_len);
        if (rc == m->om_len) {
            /* Complete write. */
            ns->ns_tx = n;
            os_mbuf_free(m);
            rc = 0;
        } else if (rc != -1) {
            /* Partial write. */
            os_mbuf_adj(m, m->om_len - rc);
            rc = 0;
        } else {
            /* Error. */
            rc = errno;
            if (rc == EAGAIN) {
                rc = 0;
            } else {
                /*
                 * Socket had an error. User should close it.
                 */
                os_mbuf_free_chain(ns->ns_tx);
                ns->ns_tx = NULL;
                rc = native_sock_err_to_mn_err(rc);
            }
            break;
        }
    }
    os_mutex_release(&nss->mtx);
    if (notify) {
        mn_socket_writable(&ns->ns_sock, rc);
    }
    return rc;
}

static int
native_sock_set_tx_buf(struct native_sock *ns, struct os_mbuf *om)
{
    struct native_sock_state *nss = &native_sock_state;
    int rc;

    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
    if (ns->ns_tx) {
        rc = MN_EAGAIN;
    } else {
        ns->ns_tx = om;
        rc = 0;
    }
    os_mutex_release(&nss->mtx);

    return rc;
}

int
native_sock_sendto(struct mn_socket *s, struct os_mbuf *m,
  struct mn_sockaddr *addr)
{
    struct native_sock *ns = (struct native_sock *)s;
    struct sockaddr_storage ss;
    struct sockaddr *sa = (struct sockaddr *)&ss;
    uint8_t tmpbuf[MYNEWT_VAL(NATIVE_SOCKETS_MAX_UDP)];
    struct os_mbuf *o;
    int sa_len;
    int off;
    int rc;

    if (ns->ns_type == SOCK_DGRAM) {
        rc = native_sock_mn_addr_to_addr(addr, sa, &sa_len);
        if (rc) {
            return rc;
        }
        off = 0;
        for (o = m; o; o = SLIST_NEXT(o, om_next)) {
            if (off + o->om_len > sizeof(tmpbuf)) {
                return MN_ENOBUFS;
            }
            os_mbuf_copydata(o, 0, o->om_len, &tmpbuf[off]);
            off += o->om_len;
        }
        rc = sendto(ns->ns_fd, tmpbuf, off, 0, sa, sa_len);
        if (rc != off) {
            return native_sock_err_to_mn_err(errno);
        }
        os_mbuf_free_chain(m);
        return 0;
    } else {
        rc = native_sock_set_tx_buf(ns, m);
        if (rc != 0) {
            return rc;
        }

        rc = native_sock_stream_tx(ns, 0);
        return rc;
    }
}

int
native_sock_recvfrom(struct mn_socket *s, struct os_mbuf **mp,
  struct mn_sockaddr *addr)
{
    struct native_sock *ns = (struct native_sock *)s;
    struct sockaddr_storage ss;
    struct sockaddr *sa = (struct sockaddr *)&ss;
    uint8_t tmpbuf[MYNEWT_VAL(NATIVE_SOCKETS_MAX_UDP)];
    struct os_mbuf *m;
    socklen_t slen;
    int rc;

    slen = sizeof(ss);
    if (ns->ns_type == SOCK_DGRAM) {
        rc = recvfrom(ns->ns_fd, tmpbuf, sizeof(tmpbuf), 0, sa, &slen);
    } else {
        rc = getpeername(ns->ns_fd, sa, &slen);
        if (rc == 0) {
            rc = read(ns->ns_fd, tmpbuf, sizeof(tmpbuf));
        }
    }
    if (rc < 0) {
        return native_sock_err_to_mn_err(errno);
    }
    if (ns->ns_type == SOCK_STREAM && rc == 0) {
        mn_socket_readable(&ns->ns_sock, MN_ECONNABORTED);
        ns->ns_poll = 0;
        native_sock_poll_rebuild(&native_sock_state);
        return MN_ECONNABORTED;
    }

    m = os_msys_get_pkthdr(rc, 0);
    if (!m) {
        return MN_ENOBUFS;
    }
    os_mbuf_copyinto(m, 0, tmpbuf, rc);
    *mp = m;
    if (addr) {
        native_sock_addr_to_mn_addr(sa, addr);
    }
    return 0;
}

int
native_sock_getsockopt(struct mn_socket *s, uint8_t level, uint8_t name,
  void *val)
{
    return MN_EPROTONOSUPPORT;
}

int
native_sock_setsockopt(struct mn_socket *s, uint8_t level, uint8_t name,
  void *val)
{
    struct native_sock *ns = (struct native_sock *)s;
    int rc;
    uint32_t val32;
    struct group_req greq;
    struct sockaddr_in *sin;
    struct sockaddr_in6 *sin6;
    struct mn_mreq *mreq;

    if (level == MN_SO_LEVEL) {
        switch (name) {
        case MN_MCAST_JOIN_GROUP:
        case MN_MCAST_LEAVE_GROUP:
            mreq = val;
            memset(&greq, 0, sizeof(greq));
            greq.gr_interface = mreq->mm_idx;
            if (mreq->mm_family == MN_AF_INET) {
                sin = (struct sockaddr_in *)&greq.gr_group;
#ifndef MN_LINUX
                sin->sin_len = sizeof(*sin);
#endif
                sin->sin_family = AF_INET;
                memcpy(&sin->sin_addr, &mreq->mm_addr, sizeof(struct in_addr));
                level = IPPROTO_IP;
            } else {
                sin6 = (struct sockaddr_in6 *)&greq.gr_group;
#ifndef MN_LINUX
                sin6->sin6_len = sizeof(*sin6);
#endif
                sin6->sin6_family = AF_INET6;
                memcpy(&sin6->sin6_addr, &mreq->mm_addr,
                  sizeof(struct in6_addr));
                level = IPPROTO_IPV6;
            }

            if (name == MN_MCAST_JOIN_GROUP) {
                name = MCAST_JOIN_GROUP;
            } else {
                name = MCAST_LEAVE_GROUP;
            }
            rc = setsockopt(ns->ns_fd, level, name, &greq, sizeof(greq));
            if (rc) {
                return native_sock_err_to_mn_err(errno);
            }
            return 0;
        case MN_MCAST_IF:
            if (ns->ns_pf == AF_INET) {
                level = IPPROTO_IP;
                name = IP_MULTICAST_IF;
                rc = native_sock_itf_addr(*(int *)val, &val32);
                if (rc) {
                    return rc;
                }
            } else {
                level = IPPROTO_IPV6;
                name = IPV6_MULTICAST_IF;
                val32 = *(uint32_t *)val;
            }
            rc = setsockopt(ns->ns_fd, level, name, &val32, sizeof(val32));
            if (rc) {
                return native_sock_err_to_mn_err(errno);
            }
            return 0;

        case MN_REUSEADDR:
            name = SO_REUSEADDR;
            val32 = *(uint32_t *)val;
            rc = setsockopt(ns->ns_fd, level, name, &val32, sizeof(val32));
            if (rc) {
                return native_sock_err_to_mn_err(errno);
            }
            return 0;
        }
    }
    return MN_EPROTONOSUPPORT;
}

int
native_sock_getsockname(struct mn_socket *s, struct mn_sockaddr *addr)
{
    struct native_sock *ns = (struct native_sock *)s;
    struct sockaddr_storage ss;
    struct sockaddr *sa = (struct sockaddr *)&ss;
    socklen_t len;
    int rc;

    len = sizeof(struct sockaddr_storage);
    rc = getsockname(ns->ns_fd, sa, &len);
    if (rc) {
        return native_sock_err_to_mn_err(errno);
    }
    rc = native_sock_addr_to_mn_addr(sa, addr);
    if (rc) {
        return rc;
    }
    return 0;
}

int
native_sock_getpeername(struct mn_socket *s, struct mn_sockaddr *addr)
{
    struct native_sock *ns = (struct native_sock *)s;
    struct sockaddr_storage ss;
    struct sockaddr *sa = (struct sockaddr *)&ss;
    socklen_t len;
    int rc;

    len = sizeof(struct sockaddr_storage);
    rc = getpeername(ns->ns_fd, sa, &len);
    if (rc) {
        return native_sock_err_to_mn_err(errno);
    }
    rc = native_sock_addr_to_mn_addr(sa, addr);
    if (rc) {
        return rc;
    }
    return 0;
}

/*
 * XXX should do this task with SIGIO as well.
 */
static void
socket_task(void *arg)
{
    struct native_sock_state *nss = arg;
    struct native_sock *ns, *new_ns;
    struct sockaddr_storage ss;
    struct sockaddr *sa = (struct sockaddr *)&ss;
    int revents;
    int i;
    socklen_t slen;
    int sock_err;
    int rc;

    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
    while (1) {
        os_mutex_release(&nss->mtx);
        os_time_delay(MYNEWT_VAL(NATIVE_SOCKETS_POLL_ITVL));
        os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
        if (nss->poll_fd_cnt) {
            rc = poll(nss->poll_fds, nss->poll_fd_cnt, 0);
        } else {
            rc = 0;
        }
        if (rc == 0) {
            continue;
        }
        for (i = 0; i < nss->poll_fd_cnt; i++) {
            if (nss->poll_fds[i].revents == 0) {
                continue;
            }

            revents = nss->poll_fds[i].revents;
            nss->poll_fds[i].revents = 0;

            ns = native_find_sock(nss->poll_fds[i].fd);
            assert(ns);

            if (revents & POLLIN) {
                if (ns->ns_listen) {
                    new_ns = native_get_sock();
                    if (!new_ns) {
                        continue;
                    }
                    slen = sizeof(ss);
                    new_ns->ns_fd = accept(ns->ns_fd, sa, &slen);
                    if (new_ns->ns_fd < 0) {
                        continue;
                    }
                    new_ns->ns_type = ns->ns_type;
                    new_ns->ns_sock.ms_ops = &native_sock_ops;
                    os_mutex_release(&nss->mtx);
                    if (mn_socket_newconn(&ns->ns_sock, &new_ns->ns_sock)) {
                        /*
                         * should close
                         */
                    }
                    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
                    new_ns->ns_poll = 1;
                    native_sock_poll_rebuild(nss);
                } else {
                    mn_socket_readable(&ns->ns_sock, 0);
                }
            }

            if (revents & POLLOUT) {
                if (ns->ns_connect) {
                    /*
                     * The connection attempt has completed.  Report whether it
                     * succeeded.
                     */
                    ns->ns_connect = 0;

                    slen = sizeof(sock_err);
                    rc = getsockopt(ns->ns_fd, SOL_SOCKET, SO_ERROR,
                                    &sock_err, &slen);
                    if (rc != 0) {
                        rc = native_sock_err_to_mn_err(errno);
                    } else if (sock_err != 0) {
                        rc = native_sock_err_to_mn_err(sock_err);
                    }
                    mn_socket_writable(&ns->ns_sock, rc);
                } else if (ns->ns_type == SOCK_STREAM && ns->ns_tx) {
                    native_sock_stream_tx(ns, 1);
                }
            }
        }
    }
}

int
native_sock_init(void)
{
    struct native_sock_state *nss = &native_sock_state;
    int i;
    os_stack_t *sp;

    /* Ensure this function only gets called by sysinit. */
    SYSINIT_ASSERT_ACTIVE();

    for (i = 0; i < MYNEWT_VAL(NATIVE_SOCKETS_MAX); i++) {
        native_socks[i].ns_fd = -1;
        STAILQ_INIT(&native_socks[i].ns_rx);
    }
    sp = malloc(sizeof(os_stack_t) * MYNEWT_VAL(NATIVE_SOCKETS_STACK_SZ));
    if (!sp) {
        return -1;
    }
    os_mutex_init(&nss->mtx);
    i = os_task_init(&nss->task, "socket", socket_task, &native_sock_state,
      MYNEWT_VAL(NATIVE_SOCKETS_PRIO), OS_WAIT_FOREVER, sp,
      MYNEWT_VAL(NATIVE_SOCKETS_STACK_SZ));
    if (i) {
        return -1;
    }
    i = mn_socket_ops_reg(&native_sock_ops);
    if (i) {
        return -1;
    }

    return 0;
}
