JNIEXPORT jint JNICALL Java_sun_nio_ch_Net_localPort(JNIEnv *env, jclass clazz, jobject fdo) { SOCKADDR sa; socklen_t sa_len = SOCKADDR_LEN; if (getsockname(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) < 0) { #ifdef _ALLBSD_SOURCE /* * XXXBSD: * ECONNRESET is specific to the BSDs. We can not return an error, * as the calling Java code with raise a java.lang.Error given the expectation * that getsockname() will never fail. According to the Single UNIX Specification, * it shouldn't fail. As such, we just fill in generic Linux-compatible values. */ if (errno == ECONNRESET) { struct sockaddr_in *sin; sin = (struct sockaddr_in *) &sa; bzero(sin, sizeof(*sin)); sin->sin_len = sizeof(struct sockaddr_in); sin->sin_family = AF_INET; sin->sin_port = htonl(0); sin->sin_addr.s_addr = INADDR_ANY; } else { handleSocketError(env, errno); return -1; } #else /* _ALLBSD_SOURCE */ handleSocketError(env, errno); return -1; #endif /* _ALLBSD_SOURCE */ } return NET_GetPortFromSockaddr((struct sockaddr *)&sa); }
JNIEXPORT jint JNICALL Java_sun_nio_ch_Net_localPort(JNIEnv *env, jclass clazz, jobject fdo) { SOCKADDR sa; int sa_len = SOCKADDR_LEN; if (getsockname(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) < 0) { handleSocketError(env, errno); return -1; } return NET_GetPortFromSockaddr((struct sockaddr *)&sa); }
JNIEXPORT jint JNICALL Java_sun_nio_ch_Net_remotePort(JNIEnv *env, jclass clazz, jobject fdo) { SOCKETADDRESS sa; int sa_len = sizeof(sa); if (getpeername(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) < 0) { int error = WSAGetLastError(); if (error == WSAEINVAL) { return 0; } NET_ThrowNew(env, error, "getsockname"); return IOS_THROWN; } return NET_GetPortFromSockaddr((struct sockaddr *)&sa); }
/* * Create the marker file descriptor by establishing a loopback connection * which we shutdown but do not close the fd. The result is an fd that * can be used for read/write. */ static int getMarkerFD() { int server_fd, child_fd, connect_fd; SOCKADDR him; int type, len, port; type = AF_INET; #ifdef AF_INET6 if (ipv6_available()) { type = AF_INET6; } #endif /* * Create listener on any port */ server_fd = JVM_Socket(type, SOCK_STREAM, 0); if (server_fd < 0) { return -1; } if (JVM_Listen(server_fd, 1) == -1) { JVM_SocketClose(server_fd); return -1; } len = SOCKADDR_LEN; if (JVM_GetSockName(server_fd, (struct sockaddr *)&him, &len) == -1) { JVM_SocketClose(server_fd); return -1; } port = NET_GetPortFromSockaddr((struct sockaddr *)&him); /* * Establish connection from client socket. * Server is bound to 0.0.0.0/X or ::/X * We connect to 127.0.0.1/X or ::1/X */ #ifdef AF_INET6 if (ipv6_available()) { struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)&him; jbyte caddr[16]; memset((char *) caddr, 0, 16); caddr[15] = 1; memset((char *)him6, 0, sizeof(struct sockaddr_in6)); memcpy((void *)&(him6->sin6_addr), caddr, sizeof(struct in6_addr) ); him6->sin6_port = htons((short) port); him6->sin6_family = AF_INET6; len = sizeof(struct sockaddr_in6) ; } else #endif /* AF_INET6 */ { struct sockaddr_in *him4 = (struct sockaddr_in*)&him; memset((char *) him4, 0, sizeof(struct sockaddr_in)); him4->sin_port = htons((short) port); him4->sin_addr.s_addr = (uint32_t) htonl(0x7f000001); him4->sin_family = AF_INET; len = sizeof(struct sockaddr_in); } connect_fd = JVM_Socket(type, SOCK_STREAM, 0); if (connect_fd < 0) { JVM_SocketClose(server_fd); return -1; } if (JVM_Connect(connect_fd, (struct sockaddr *) &him, len) == -1) { JVM_SocketClose(server_fd); JVM_SocketClose(connect_fd); return -1; } /* * Server accepts connection - do in in non-blocking mode to avoid * hanging if there's an error (should never happen!!!) */ SET_NONBLOCKING(server_fd); len = SOCKADDR_LEN; child_fd = JVM_Accept(server_fd, (struct sockaddr *)&him, (jint *)&len); if (child_fd == -1) { JVM_SocketClose(server_fd); JVM_SocketClose(connect_fd); return -1; } /* * Finally shutdown connect_fd (any reads to this fd will get * EOF; any writes will get an error). */ JVM_SocketShutdown(connect_fd, 2); JVM_SocketClose(child_fd); JVM_SocketClose(server_fd); return connect_fd; }