コード例 #1
0
ファイル: netty_epoll_native.c プロジェクト: Big-Header/netty
static jint netty_epoll_native_epollCreate(JNIEnv* env, jclass clazz) {
    jint efd;
    if (epoll_create1) {
        efd = epoll_create1(EPOLL_CLOEXEC);
    } else {
        // size will be ignored anyway but must be positive
        efd = epoll_create(126);
    }
    if (efd < 0) {
        int err = errno;
        if (epoll_create1) {
            netty_unix_errors_throwChannelExceptionErrorNo(env, "epoll_create1() failed: ", err);
        } else {
            netty_unix_errors_throwChannelExceptionErrorNo(env, "epoll_create() failed: ", err);
        }
        return efd;
    }
    if (!epoll_create1) {
        if (fcntl(efd, F_SETFD, FD_CLOEXEC) < 0) {
            int err = errno;
            close(efd);
            netty_unix_errors_throwChannelExceptionErrorNo(env, "fcntl() failed: ", err);
            return err;
        }
    }
    return efd;
}
コード例 #2
0
ファイル: netty_epoll_native.c プロジェクト: Big-Header/netty
static void netty_epoll_native_eventFdWrite(JNIEnv* env, jclass clazz, jint fd, jlong value) {
    jint eventFD = eventfd_write(fd, (eventfd_t) value);

    if (eventFD < 0) {
        netty_unix_errors_throwChannelExceptionErrorNo(env, "eventfd_write() failed: ", errno);
    }
}
コード例 #3
0
ファイル: netty_epoll_native.c プロジェクト: Big-Header/netty
static void netty_epoll_native_timerFdRead(JNIEnv* env, jclass clazz, jint fd) {
    uint64_t timerFireCount;

    if (read(fd, &timerFireCount, sizeof(uint64_t)) < 0) {
        // it is expected that this is only called where there is known to be activity, so this is an error.
        netty_unix_errors_throwChannelExceptionErrorNo(env, "read() failed: ", errno);
    }
}
コード例 #4
0
JNIEXPORT void JNICALL Java_io_netty_channel_epoll_Native_eventFdWrite(JNIEnv* env, jclass clazz, jint fd, jlong value) {
    jint eventFD = eventfd_write(fd, (eventfd_t) value);

    if (eventFD < 0) {
        int err = errno;
        netty_unix_errors_throwChannelExceptionErrorNo(env, "eventfd_write() failed: ", err);
    }
}
コード例 #5
0
ファイル: netty_epoll_native.c プロジェクト: Big-Header/netty
static jint netty_epoll_native_timerFd(JNIEnv* env, jclass clazz) {
    jint timerFD = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);

    if (timerFD < 0) {
        netty_unix_errors_throwChannelExceptionErrorNo(env, "timerfd_create() failed: ", errno);
    }
    return timerFD;
}
コード例 #6
0
JNIEXPORT void JNICALL Java_io_netty_channel_epoll_Native_setTrafficClass(JNIEnv* env, jclass clazz, jint fd, jint optval) {
    netty_unix_socket_setOption(env, fd, IPPROTO_IP, IP_TOS, &optval, sizeof(optval));

    /* Try to set the ipv6 equivalent, but don't throw if this is an ipv4 only socket. */
    int rc = setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &optval, sizeof(optval));
    if (rc < 0 && errno != ENOPROTOOPT) {
        netty_unix_errors_throwChannelExceptionErrorNo(env, "setting ipv6 dscp failed: ", errno);
    }
}
コード例 #7
0
JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_eventFd(JNIEnv* env, jclass clazz) {
    jint eventFD = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);

    if (eventFD < 0) {
        int err = errno;
        netty_unix_errors_throwChannelExceptionErrorNo(env, "eventfd() failed: ", err);
    }
    return eventFD;
}
コード例 #8
0
static jobjectArray netty_kqueue_bsdsocket_getAcceptFilter(JNIEnv* env, jclass clazz, jint fd) {
#ifdef SO_ACCEPTFILTER
    struct accept_filter_arg af;
    if (netty_unix_socket_getOption(env, fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, sizeof(af)) == -1) {
        netty_unix_errors_throwChannelExceptionErrorNo(env, "getsockopt() failed: ", errno);
        return NULL;
    }
    jobjectArray resultArray = (*env)->NewObjectArray(env, 2, stringCls, NULL);
    (*env)->SetObjectArrayElement(env, resultArray, 0, (*env)->NewStringUTF(env, &af.af_name[0]));
    (*env)->SetObjectArrayElement(env, resultArray, 1, (*env)->NewStringUTF(env, &af.af_arg[0]));
    return resultArray;
#else // No know replacement on MacOS
    // Don't throw here because this is used when getting a list of all options.
    return NULL;
#endif
}
コード例 #9
0
ファイル: netty_epoll_native.c プロジェクト: Big-Header/netty
static inline jint epollCtl(JNIEnv* env, jint efd, int op, jint fd, jint flags) {
    uint32_t events = flags;
    struct epoll_event ev = {
        .data.fd = fd,
        .events = events
    };

    return epoll_ctl(efd, op, fd, &ev);
}
// JNI Registered Methods Begin
static jint netty_epoll_native_eventFd(JNIEnv* env, jclass clazz) {
    jint eventFD = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);

    if (eventFD < 0) {
        netty_unix_errors_throwChannelExceptionErrorNo(env, "eventfd() failed: ", errno);
    }
    return eventFD;
}
コード例 #10
0
ファイル: netty_epoll_native.c プロジェクト: Big-Header/netty
static jint netty_epoll_native_epollWait0(JNIEnv* env, jclass clazz, jint efd, jlong address, jint len, jint timerFd, jint tvSec, jint tvNsec) {
    struct epoll_event *ev = (struct epoll_event*) (intptr_t) address;
    int result, err;

    if (tvSec == 0 && tvNsec == 0) {
        // Zeros = poll (aka return immediately).
        do {
            result = epoll_wait(efd, ev, len, 0);
            if (result >= 0) {
                return result;
            }
        } while((err = errno) == EINTR);
    } else {
        // only reschedule the timer if there is a newer event.
        // -1 is a special value used by EpollEventLoop.
        if (tvSec != ((jint) -1) && tvNsec != ((jint) -1)) {
            struct itimerspec ts;
            memset(&ts.it_interval, 0, sizeof(struct timespec));
            ts.it_value.tv_sec = tvSec;
            ts.it_value.tv_nsec = tvNsec;
            if (timerfd_settime(timerFd, 0, &ts, NULL) < 0) {
                netty_unix_errors_throwChannelExceptionErrorNo(env, "timerfd_settime() failed: ", errno);
                return -1;
            }
        }
        do {
            result = epoll_wait(efd, ev, len, -1);
            if (result > 0) {
                // Detect timeout, and preserve the epoll_wait API.
                if (result == 1 && ev[0].data.fd == timerFd) {
                    // We assume that timerFD is in ET mode. So we must consume this event to ensure we are notified
                    // of future timer events because ET mode only notifies a single time until the event is consumed.
                    uint64_t timerFireCount;
                    // We don't care what the result is. We just want to consume the wakeup event and reset ET.
                    result = read(timerFd, &timerFireCount, sizeof(uint64_t));
                    return 0;
                }
                return result;
            }
        } while((err = errno) == EINTR);
    }
    return -err;
}
コード例 #11
0
static void netty_kqueue_bsdsocket_setAcceptFilter(JNIEnv* env, jclass clazz, jint fd, jstring afName, jstring afArg) {
#ifdef SO_ACCEPTFILTER
    struct accept_filter_arg af;
    const char* tmpString = NULL;
    af.af_name[0] = af.af_arg[0] ='\0';

    tmpString = (*env)->GetStringUTFChars(env, afName, NULL);
    strncat(af.af_name, tmpString, sizeof(af.af_name) / sizeof(af.af_name[0]));
    (*env)->ReleaseStringUTFChars(env, afName, tmpString);

    tmpString = (*env)->GetStringUTFChars(env, afArg, NULL);
    strncat(af.af_arg, tmpString, sizeof(af.af_arg) / sizeof(af.af_arg[0]));
    (*env)->ReleaseStringUTFChars(env, afArg, tmpString);

    netty_unix_socket_setOption(env, fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, sizeof(af));
#else // No know replacement on MacOS
    netty_unix_errors_throwChannelExceptionErrorNo(env, "setsockopt() failed: ", EINVAL);
#endif
}
コード例 #12
0
JNIEXPORT void JNICALL Java_io_netty_channel_epoll_Native_setTcpMd5Sig0(JNIEnv* env, jclass clazz, jint fd, jbyteArray address, jint scopeId, jbyteArray key) {
    struct sockaddr_storage addr;
    if (netty_unix_socket_initSockaddr(env, address, scopeId, 0, &addr) == -1) {
        return;
    }

    struct tcp_md5sig md5sig;
    memset(&md5sig, 0, sizeof(md5sig));
    md5sig.tcpm_addr.ss_family = addr.ss_family;

    struct sockaddr_in* ipaddr;
    struct sockaddr_in6* ip6addr;

    switch (addr.ss_family) {
    case AF_INET:
        ipaddr = (struct sockaddr_in*) &addr;
        memcpy(&((struct sockaddr_in *) &md5sig.tcpm_addr)->sin_addr, &ipaddr->sin_addr, sizeof(ipaddr->sin_addr));
        break;
    case AF_INET6:
        ip6addr = (struct sockaddr_in6*) &addr;
        memcpy(&((struct sockaddr_in6 *) &md5sig.tcpm_addr)->sin6_addr, &ip6addr->sin6_addr, sizeof(ip6addr->sin6_addr));
        break;
    }

    if (key != NULL) {
        md5sig.tcpm_keylen = (*env)->GetArrayLength(env, key);
        (*env)->GetByteArrayRegion(env, key, 0, md5sig.tcpm_keylen, (void *) &md5sig.tcpm_key);
        if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
            return;
        }
    }

    if (setsockopt(fd, IPPROTO_TCP, TCP_MD5SIG, &md5sig, sizeof(md5sig)) < 0) {
        netty_unix_errors_throwChannelExceptionErrorNo(env, "setsockopt() failed: ", errno);
    }
}