Esempio n. 1
0
JNIEXPORT void JNICALL
Java_sun_nio_ch_Net_bind(JNIEnv *env, jclass clazz, /* ## Needs rest of PSI gunk */
			 jobject fdo, jobject ia, int port)
{
    SOCKADDR sa;
    int sa_len = SOCKADDR_LEN;
    int rv = 0;

    NET_InetAddressToSockaddr(env, ia, port, (struct sockaddr *)&sa, &sa_len);

    rv = NET_Bind(fdval(env, fdo), (struct sockaddr *)&sa, sa_len);
    if (rv != 0) {
        handleSocketError(env, errno);
    }
}
/*
 * Class:     java_net_DualStackPlainSocketImpl
 * Method:    bind0
 * Signature: (ILjava/net/InetAddress;I)V
 */
JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_bind0
  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) {
    SOCKETADDRESS sa;
    int rv;
    int sa_len = sizeof(sa);

    if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa,
                                 &sa_len, JNI_TRUE) != 0) {
      return;
    }

    rv = NET_Bind(fd, (struct sockaddr *)&sa, sa_len);

    if (rv == SOCKET_ERROR)
        NET_ThrowNew(env, WSAGetLastError(), "JVM_Bind");
}
Esempio n. 3
0
JNIEXPORT void JNICALL
Java_sun_nio_ch_Net_bind0(JNIEnv *env, jclass clazz, jobject fdo, jboolean preferIPv6,
                          jboolean useExclBind, jobject iao, int port)
{
    SOCKADDR sa;
    int sa_len = SOCKADDR_LEN;
    int rv = 0;

    if (NET_InetAddressToSockaddr(env, iao, port, (struct sockaddr *)&sa, &sa_len, preferIPv6) != 0) {
      return;
    }

    rv = NET_Bind(fdval(env, fdo), (struct sockaddr *)&sa, sa_len);
    if (rv != 0) {
        handleSocketError(env, errno);
    }
}
Esempio n. 4
0
JNIEXPORT int JNICALL
NET_BindV6(struct ipv6bind* b) {
    int fd=-1, ofd=-1, rv, len;
    /* need to defer close until new sockets created */
    int close_fd=-1, close_ofd=-1; 
    SOCKETADDRESS oaddr; /* other address to bind */
    int family = b->addr->him.sa_family;
    int ofamily;
    u_short port; /* requested port parameter */
    u_short bound_port;

    if (family == AF_INET && (b->addr->him4.sin_addr.s_addr != INADDR_ANY)) {
	/* bind to v4 only */
	int ret;
	ret = NET_Bind (b->ipv4_fd, (struct sockaddr *)b->addr, 
				sizeof (struct sockaddr_in));
        if (ret == SOCKET_ERROR) {
	    CLOSE_SOCKETS_AND_RETURN;
        }
	closesocket (b->ipv6_fd);
	b->ipv6_fd = -1;
	return 0;
    }
    if (family == AF_INET6 && (!IN6_IS_ADDR_ANY(&b->addr->him6.sin6_addr))) {
	/* bind to v6 only */
	int ret;
	ret = NET_Bind (b->ipv6_fd, (struct sockaddr *)b->addr, 
				sizeof (struct SOCKADDR_IN6));
        if (ret == SOCKET_ERROR) {
	    CLOSE_SOCKETS_AND_RETURN;
        }
	closesocket (b->ipv4_fd);
	b->ipv4_fd = -1;
	return 0;
    }

    /* We need to bind on both stacks, with the same port number */

    memset (&oaddr, 0, sizeof(oaddr));
    if (family == AF_INET) {
	ofamily = AF_INET6;
	fd = b->ipv4_fd;
	ofd = b->ipv6_fd;
	port = (u_short)GET_PORT (b->addr);
	IN6ADDR_SETANY (&oaddr.him6);
	oaddr.him6.sin6_port = port;
    } else {
	ofamily = AF_INET;
	ofd = b->ipv4_fd;
	fd = b->ipv6_fd;
	port = (u_short)GET_PORT (b->addr);
	oaddr.him4.sin_family = AF_INET;
	oaddr.him4.sin_port = port;
	oaddr.him4.sin_addr.s_addr = INADDR_ANY;
    }

    rv = NET_Bind (fd, (struct sockaddr *)b->addr, SOCKETADDRESS_LEN(b->addr));
    if (rv == SOCKET_ERROR) {
    	CLOSE_SOCKETS_AND_RETURN;
    }

    /* get the port and set it in the other address */
    len = SOCKETADDRESS_LEN(b->addr);
    if (getsockname(fd, (struct sockaddr *)b->addr, &len) == -1) {
    	CLOSE_SOCKETS_AND_RETURN;
    }
    bound_port = GET_PORT (b->addr);
    SET_PORT (&oaddr, bound_port);
    if ((rv=NET_Bind (ofd, (struct sockaddr *) &oaddr, 
				SOCKETADDRESS_LEN (&oaddr))) == SOCKET_ERROR) {
	int retries;
	int sotype, arglen=sizeof(sotype);

 	/* no retries unless, the request was for any free port */

        if (port != 0) {
    	    CLOSE_SOCKETS_AND_RETURN;
        }

	getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, &arglen);

#define SOCK_RETRIES 50
	/* 50 is an arbitrary limit, just to ensure that this
	 * cannot be an endless loop. Would expect socket creation to 
	 * succeed sooner.
	 */
    	for (retries = 0; retries < SOCK_RETRIES; retries ++) {
	    int len;
	    close_fd = fd; fd = -1;
	    close_ofd = ofd; ofd = -1;
	    b->ipv4_fd = SOCKET_ERROR;
	    b->ipv6_fd = SOCKET_ERROR;

	    /* create two new sockets */
	    fd = socket (family, sotype, 0);
	    if (fd == SOCKET_ERROR) {
    	        CLOSE_SOCKETS_AND_RETURN;
	    }
	    ofd = socket (ofamily, sotype, 0);
	    if (ofd == SOCKET_ERROR) {
    	        CLOSE_SOCKETS_AND_RETURN;
	    }

	    /* bind random port on first socket */
	    SET_PORT (&oaddr, 0);
    	    rv = NET_Bind (ofd, (struct sockaddr *)&oaddr, SOCKETADDRESS_LEN(&oaddr));
    	    if (rv == SOCKET_ERROR) {
    	        CLOSE_SOCKETS_AND_RETURN;
	    }
	    /* close the original pair of sockets before continuing */
	    closesocket (close_fd); 
	    closesocket (close_ofd); 
	    close_fd = close_ofd = -1;

	    /* bind new port on second socket */
	    len = SOCKETADDRESS_LEN(&oaddr);
            if (getsockname(ofd, (struct sockaddr *)&oaddr, &len) == -1) {
    	        CLOSE_SOCKETS_AND_RETURN;
            }
    	    bound_port = GET_PORT (&oaddr);
	    SET_PORT (b->addr, bound_port);
    	    rv = NET_Bind (fd, (struct sockaddr *)b->addr, SOCKETADDRESS_LEN(b->addr));

    	    if (rv != SOCKET_ERROR) {
		if (family == AF_INET) {
	    	    b->ipv4_fd = fd;
	    	    b->ipv6_fd = ofd;
		} else {
	    	    b->ipv4_fd = ofd;
	    	    b->ipv6_fd = fd;
		}
		return 0;
	    }
	}
	CLOSE_SOCKETS_AND_RETURN;
    }
    return 0;
}