📄 jni_socket.c
字号:
resin_throw_exception(env, "com/caucho/config/ConfigException", "can't load _remoteAddrLength field"); ss->_remotePort = (*env)->GetFieldID(env, jniServerSocketClass, "_remotePort", "I"); if (! ss->_remotePort) resin_throw_exception(env, "com/caucho/config/ConfigException", "can't load _remotePort field"); }}JNIEXPORT jlong JNICALLJava_com_caucho_vfs_JniServerSocketImpl_bindPort(JNIEnv *env, jobject obj, jstring jaddr, jint port){ int val = 0; char addr_name[256]; const char *temp_string = 0; int sock; int family; int protocol; server_socket_t *ss; char sin_data[256]; struct sockaddr_in *sin; int sin_length;#ifdef WIN32 { WSADATA data; WORD version = MAKEWORD(2,2); WSAStartup(version, &data); }#endif addr_name[0] = 0; if (jaddr != 0) { temp_string = (*env)->GetStringUTFChars(env, jaddr, 0); if (temp_string) { strncpy(addr_name, temp_string, sizeof(addr_name)); addr_name[sizeof(addr_name) - 1] = 0; (*env)->ReleaseStringUTFChars(env, jaddr, temp_string); } } if (temp_string == 0) { resin_throw_exception(env, "java/lang/NullPointerException", "missing addr"); return 0; } sin = lookup_addr(env, addr_name, port, sin_data, &family, &protocol, &sin_length); if (! sin) return 0; sock = socket(family, SOCK_STREAM, 0); if (sock < 0) { return 0; } val = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(int)) < 0) { closesocket(sock); return 0; } if (bind(sock, (struct sockaddr *) sin, sin_length) < 0) { int i = 5; int result = 0; /* somewhat of a hack to clear the old connection. */ while (result == 0 && i-- >= 0) { int fd = socket(AF_INET, SOCK_STREAM, 0); result = connect(fd, (struct sockaddr *) &sin, sizeof(sin)); closesocket(fd); } result = -1; for (i = 50; result < 0 && i >= 0; i--) { result = bind(sock, (struct sockaddr *) sin, sin_length); if (result < 0) { struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 100000; select(0, 0, 0, 0, &tv); } } if (result < 0) { closesocket(sock); return 0; } } /* must be 0 if the poll is missing for accept */#if 0 && defined(O_NONBLOCK) /* * sets nonblock to ensure the timeout work in the case of multiple threads. */ { int flags; int result; flags = fcntl(sock, F_GETFL); result = fcntl(sock, F_SETFL, O_NONBLOCK|flags); }#endif ss = (server_socket_t *) cse_malloc(sizeof(server_socket_t)); memset(ss, 0, sizeof(server_socket_t)); ss->fd = sock; ss->port = port; ss->conn_socket_timeout = 65000; ss->accept = &std_accept; ss->close = &std_close_ss;#ifdef WIN32 ss->accept_lock = CreateMutex(0, 0, 0); ss->ssl_lock = CreateMutex(0, 0, 0);#endif init_server_socket(env, ss); return (PTR) ss;}JNIEXPORT jlong JNICALLJava_com_caucho_vfs_JniServerSocketImpl_nativeOpenPort(JNIEnv *env, jobject obj, jint sock, jint port){ server_socket_t *ss;#ifdef WIN32 { WSADATA data; WORD version = MAKEWORD(2,2); WSAStartup(version, &data); }#endif if (sock < 0) return 0; ss = (server_socket_t *) cse_malloc(sizeof(server_socket_t)); if (ss == 0) return 0; memset(ss, 0, sizeof(server_socket_t)); ss->fd = sock; ss->port = port; ss->conn_socket_timeout = 65000; ss->accept = &std_accept; ss->close = &std_close_ss;#ifdef WIN32 ss->accept_lock = CreateMutex(0, 0, 0); ss->ssl_lock = CreateMutex(0, 0, 0);#endif init_server_socket(env, ss); return (PTR) ss;}JNIEXPORT void JNICALLJava_com_caucho_vfs_JniServerSocketImpl_nativeSetConnectionSocketTimeout(JNIEnv *env, jobject obj, jlong ss_fd, jint timeout){ server_socket_t *ss = (server_socket_t *) (PTR) ss_fd; if (! ss) return; if (timeout < 0) timeout = 600 * 1000; else if (timeout < 500) timeout = 500; ss->conn_socket_timeout = timeout;}JNIEXPORT void JNICALLJava_com_caucho_vfs_JniServerSocketImpl_nativeListen(JNIEnv *env, jobject obj, jlong ss_fd, jint backlog){ server_socket_t *ss = (server_socket_t *) (PTR) ss_fd; if (! ss || ss->fd < 0) return; if (backlog < 0) backlog = 0; if (backlog < 0) listen(ss->fd, 100); else listen(ss->fd, backlog);}JNIEXPORT jboolean JNICALLJava_com_caucho_vfs_JniServerSocketImpl_nativeAccept(JNIEnv *env, jobject obj, jlong ss_fd, jlong conn_fd){ server_socket_t *socket = (server_socket_t *) (PTR) ss_fd; connection_t *conn = (connection_t *) (PTR) conn_fd; jboolean value; if (! socket || ! conn) return 0; value = socket->accept(socket, conn); return value;}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniServerSocketImpl_getLocalPort(JNIEnv *env, jobject obj, jlong ss){ server_socket_t *socket = (server_socket_t *) (PTR) ss; if (! socket) return 0; else return socket->port;}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniServerSocketImpl_nativeGetSystemFD(JNIEnv *env, jobject obj, jlong ss){ server_socket_t *socket = (server_socket_t *) (PTR) ss; if (! socket) return -1; else return socket->fd;}JNIEXPORT jboolean JNICALLJava_com_caucho_vfs_JniServerSocketImpl_nativeSetSaveOnExec(JNIEnv *env, jobject obj, jlong ss){#ifdef WIN32 return 0;#else server_socket_t *socket = (server_socket_t *) (PTR) ss; if (! socket) return 0; else { int fd = socket->fd; int arg = 0; if (fd < 0) return 0; /* sets the close on exec flag */ arg = fcntl(fd, F_GETFD, 0); arg &= ~FD_CLOEXEC; return fcntl(fd, F_SETFD, arg) >= 0; }#endif}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniServerSocketImpl_closeNative(JNIEnv *env, jobject obj, jlong ss){ server_socket_t *socket = (server_socket_t *) (PTR) ss; if (! socket) return 0; socket->close(socket); cse_free(socket); return 0;}#if ! defined(AF_INET6) || defined(WIN32)static intget_address(struct sockaddr *addr, char *dst, int length){ struct sockaddr_in *sin = (struct sockaddr_in *) addr; char *result; if (! sin) return 0; result = inet_ntoa(sin->sin_addr); if (result) { strncpy(dst, result, length); dst[length - 1] = 0; return strlen(dst); } else return 0;}#elsestatic intget_address(struct sockaddr *addr, char *dst, int length){ struct sockaddr_in *sin = (struct sockaddr_in *) addr; const char *result; if (sin->sin_family == AF_INET6) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sin; result = inet_ntop(AF_INET6, &sin6->sin6_addr, dst, length); } else { result = inet_ntop(AF_INET, &sin->sin_addr, dst, length); } if (! result) return 0; else return strlen(result);}#endifJNIEXPORT jboolean JNICALLJava_com_caucho_vfs_JniSocketImpl_nativeInit(JNIEnv *env, jobject obj, jlong conn_fd){ connection_t *conn = (connection_t *) (PTR) conn_fd; server_socket_t *ss; if (! conn || ! env || ! obj) return 0; ss = conn->ss; if (! ss) return 0; if (ss->_isSecure) { jboolean is_secure = conn->sock != 0 && conn->ssl_cipher != 0; (*env)->SetBooleanField(env, obj, ss->_isSecure, is_secure); } if (ss->_localAddrBuffer && ss->_localAddrLength) { jbyteArray addrBuffer; char temp_buf[1024]; int len; addrBuffer = (*env)->GetObjectField(env, obj, ss->_localAddrBuffer); if (addrBuffer) { /* the 256 must match JniServerImpl */ len = get_address(conn->server_sin, temp_buf, 256); set_byte_array_region(env, addrBuffer, 0, len, temp_buf); (*env)->SetIntField(env, obj, ss->_localAddrLength, len); } } if (ss->_localPort) { struct sockaddr_in *sin = (struct sockaddr_in *) conn->server_sin; jint local_port = ntohs(sin->sin_port); (*env)->SetIntField(env, obj, ss->_localPort, local_port); } if (ss->_remoteAddrBuffer && ss->_remoteAddrLength) { jbyteArray addrBuffer; char temp_buf[1024]; int len; addrBuffer = (*env)->GetObjectField(env, obj, ss->_remoteAddrBuffer); if (addrBuffer) { /* the 256 must match JniServerImpl */ len = get_address(conn->client_sin, temp_buf, 256); set_byte_array_region(env, addrBuffer, 0, len, temp_buf); (*env)->SetIntField(env, obj, ss->_remoteAddrLength, len); } } if (ss->_remotePort) { struct sockaddr_in *sin = (struct sockaddr_in *) conn->client_sin; jint remote_port = ntohs(sin->sin_port); (*env)->SetIntField(env, obj, ss->_remotePort, remote_port); } return 1;}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniSocketImpl_getRemoteIP(JNIEnv *env, jobject obj, jlong conn_fd, jbyteArray j_buffer, jint offset, jint length){ connection_t *conn = (connection_t *) (PTR) conn_fd; int len = 0; char temp_buf[1024]; if (! conn || ! j_buffer || ! env) return 0; len = get_address(conn->client_sin, temp_buf, sizeof(temp_buf)); if (len > 0 && len < sizeof(temp_buf) && len < length) set_byte_array_region(env, j_buffer, offset, len, temp_buf); return len;}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniSocketImpl_getRemotePort(JNIEnv *env, jobject obj, jlong conn_fd){ connection_t *conn = (connection_t *) (PTR) conn_fd; struct sockaddr_in *sin; if (! conn) return 0; sin = (struct sockaddr_in *) conn->client_sin; return ntohs(sin->sin_port);}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniSocketImpl_getLocalIP(JNIEnv *env, jobject obj, jlong conn_fd, jbyteArray buffer, jint offset, jint length){ connection_t *conn = (connection_t *) (PTR) conn_fd; int len = 0; char temp_buf[1024]; if (! conn) return 0; len = get_address(conn->server_sin, temp_buf, length); set_byte_array_region(env, buffer, offset, len, temp_buf); return len;}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniSocketImpl_getLocalPort(JNIEnv *env, jobject obj, jlong conn_fd){ connection_t *conn = (connection_t *) (PTR) conn_fd; struct sockaddr_in *sin; if (! conn) return 0; sin = (struct sockaddr_in *) conn->server_sin; return ntohs(sin->sin_port);}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniSocketImpl_getClientCertificate(JNIEnv *env, jobject obj, jlong conn_fd, jbyteArray buf, jint offset, jint length){ connection_t *conn = (connection_t *) (PTR) conn_fd; int sublen; char buffer[8192]; if (! conn) return -1; if (length < 8192) sublen = length; else sublen = 8192; sublen = conn->ops->read_client_certificate(conn, buffer, sublen); /* Should probably have a different response for EINTR */ if (sublen < 0 || length < sublen) return sublen; set_byte_array_region(env, buf, offset, sublen, buffer); return sublen;}JNIEXPORT jint JNICALLJava_com_caucho_vfs_JniSocketImpl_getNativeFd(JNIEnv *env, jobject obj, jlong conn_fd){ connection_t *conn = (connection_t *) (PTR) conn_fd; if (! conn) return -1; else return conn->fd;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -