< prev index next >

src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c

Print this page
rev 59105 : imported patch corelibs


  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 #include <errno.h>
  26 #include <stdlib.h>
  27 #include <string.h>
  28 #include <sys/ioctl.h>
  29 
  30 #if defined(__solaris__)
  31 #include <sys/filio.h>
  32 #endif
  33 
  34 #include "net_util.h"
  35 
  36 #include "java_net_PlainDatagramSocketImpl.h"
  37 #include "java_net_InetAddress.h"
  38 #include "java_net_NetworkInterface.h"
  39 #include "java_net_SocketOptions.h"
  40 
  41 #ifdef __linux__
  42 #define IPV6_MULTICAST_IF 17
  43 #ifndef SO_BSDCOMPAT
  44 #define SO_BSDCOMPAT  14
  45 #endif
  46 /**
  47  * IP_MULTICAST_ALL has been supported since kernel version 2.6.31
  48  * but we may be building on a machine that is older than that.
  49  */
  50 #ifndef IP_MULTICAST_ALL
  51 #define IP_MULTICAST_ALL      49
  52 #endif
  53 #endif  //  __linux__
  54 
  55 #ifdef __solaris__
  56 #ifndef BSD_COMP
  57 #define BSD_COMP
  58 #endif
  59 #endif
  60 
  61 #ifndef IPTOS_TOS_MASK
  62 #define IPTOS_TOS_MASK 0x1e
  63 #endif
  64 #ifndef IPTOS_PREC_MASK
  65 #define IPTOS_PREC_MASK 0xe0
  66 #endif
  67 
  68 /************************************************************************
  69  * PlainDatagramSocketImpl
  70  */
  71 
  72 static jfieldID IO_fd_fdID;
  73 
  74 static jfieldID pdsi_fdID;
  75 static jfieldID pdsi_timeoutID;
  76 static jfieldID pdsi_trafficClassID;
  77 static jfieldID pdsi_localPortID;
  78 static jfieldID pdsi_connected;
  79 static jfieldID pdsi_connectedAddress;
  80 static jfieldID pdsi_connectedPort;


 481         if (ret == 0) {
 482             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
 483                             "Peek timed out");
 484             return ret;
 485         } else if (ret == -1) {
 486             if (errno == EBADF) {
 487                  JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
 488             } else if (errno == ENOMEM) {
 489                  JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");
 490             } else {
 491                  JNU_ThrowByNameWithMessageAndLastError
 492                      (env, JNU_JAVANETPKG "SocketException", "Peek failed");
 493             }
 494             return ret;
 495         }
 496     }
 497 
 498     n = NET_RecvFrom(fd, buf, 1, MSG_PEEK, &rmtaddr.sa, &slen);
 499 
 500     if (n == -1) {
 501 
 502 #ifdef __solaris__
 503         if (errno == ECONNREFUSED) {
 504             int orig_errno = errno;
 505             recv(fd, buf, 1, 0);
 506             errno = orig_errno;
 507         }
 508 #endif
 509         if (errno == ECONNREFUSED) {
 510             JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
 511                             "ICMP Port Unreachable");
 512         } else {
 513             if (errno == EBADF) {
 514                  JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
 515             } else {
 516                  JNU_ThrowByNameWithMessageAndLastError
 517                      (env, JNU_JAVANETPKG "SocketException", "Peek failed");
 518             }
 519         }
 520         return 0;
 521     }
 522 
 523     iaObj = NET_SockaddrToInetAddress(env, &rmtaddr, &port);
 524     family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
 525         AF_INET : AF_INET6;
 526     JNU_CHECK_EXCEPTION_RETURN(env, -1);
 527     if (family == AF_INET) { /* this API can't handle IPV6 addresses */
 528         int address = getInetAddress_addr(env, iaObj);


 615         }
 616         fullPacket = (char *)malloc(packetBufferLen);
 617 
 618         if (!fullPacket) {
 619             JNU_ThrowOutOfMemoryError(env, "Peek buffer native heap allocation failed");
 620             return -1;
 621         } else {
 622             mallocedPacket = JNI_TRUE;
 623         }
 624     } else {
 625         fullPacket = &(BUF[0]);
 626     }
 627 
 628     n = NET_RecvFrom(fd, fullPacket, packetBufferLen, MSG_PEEK,
 629                      &rmtaddr.sa, &slen);
 630     /* truncate the data if the packet's length is too small */
 631     if (n > packetBufferLen) {
 632         n = packetBufferLen;
 633     }
 634     if (n == -1) {
 635 
 636 #ifdef __solaris__
 637         if (errno == ECONNREFUSED) {
 638             int orig_errno = errno;
 639             (void) recv(fd, fullPacket, 1, 0);
 640             errno = orig_errno;
 641         }
 642 #endif
 643         (*env)->SetIntField(env, packet, dp_offsetID, 0);
 644         (*env)->SetIntField(env, packet, dp_lengthID, 0);
 645         if (errno == ECONNREFUSED) {
 646             JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
 647                             "ICMP Port Unreachable");
 648         } else {
 649             if (errno == EBADF) {
 650                  JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
 651             } else {
 652                  JNU_ThrowByNameWithMessageAndLastError
 653                      (env, JNU_JAVANETPKG "SocketException", "Receive failed");
 654             }
 655         }
 656     } else {
 657         /*
 658          * success - fill in received address...
 659          *
 660          * REMIND: Fill in an int on the packet, and create inetadd
 661          * object in Java, as a performance improvement. Also
 662          * construct the inetadd object lazily.




  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 #include <errno.h>
  26 #include <stdlib.h>
  27 #include <string.h>
  28 #include <sys/ioctl.h>
  29 




  30 #include "net_util.h"
  31 
  32 #include "java_net_PlainDatagramSocketImpl.h"
  33 #include "java_net_InetAddress.h"
  34 #include "java_net_NetworkInterface.h"
  35 #include "java_net_SocketOptions.h"
  36 
  37 #ifdef __linux__
  38 #define IPV6_MULTICAST_IF 17
  39 #ifndef SO_BSDCOMPAT
  40 #define SO_BSDCOMPAT  14
  41 #endif
  42 /**
  43  * IP_MULTICAST_ALL has been supported since kernel version 2.6.31
  44  * but we may be building on a machine that is older than that.
  45  */
  46 #ifndef IP_MULTICAST_ALL
  47 #define IP_MULTICAST_ALL      49
  48 #endif
  49 #endif  //  __linux__
  50 






  51 #ifndef IPTOS_TOS_MASK
  52 #define IPTOS_TOS_MASK 0x1e
  53 #endif
  54 #ifndef IPTOS_PREC_MASK
  55 #define IPTOS_PREC_MASK 0xe0
  56 #endif
  57 
  58 /************************************************************************
  59  * PlainDatagramSocketImpl
  60  */
  61 
  62 static jfieldID IO_fd_fdID;
  63 
  64 static jfieldID pdsi_fdID;
  65 static jfieldID pdsi_timeoutID;
  66 static jfieldID pdsi_trafficClassID;
  67 static jfieldID pdsi_localPortID;
  68 static jfieldID pdsi_connected;
  69 static jfieldID pdsi_connectedAddress;
  70 static jfieldID pdsi_connectedPort;


 471         if (ret == 0) {
 472             JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
 473                             "Peek timed out");
 474             return ret;
 475         } else if (ret == -1) {
 476             if (errno == EBADF) {
 477                  JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
 478             } else if (errno == ENOMEM) {
 479                  JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");
 480             } else {
 481                  JNU_ThrowByNameWithMessageAndLastError
 482                      (env, JNU_JAVANETPKG "SocketException", "Peek failed");
 483             }
 484             return ret;
 485         }
 486     }
 487 
 488     n = NET_RecvFrom(fd, buf, 1, MSG_PEEK, &rmtaddr.sa, &slen);
 489 
 490     if (n == -1) {








 491         if (errno == ECONNREFUSED) {
 492             JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
 493                             "ICMP Port Unreachable");
 494         } else {
 495             if (errno == EBADF) {
 496                  JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
 497             } else {
 498                  JNU_ThrowByNameWithMessageAndLastError
 499                      (env, JNU_JAVANETPKG "SocketException", "Peek failed");
 500             }
 501         }
 502         return 0;
 503     }
 504 
 505     iaObj = NET_SockaddrToInetAddress(env, &rmtaddr, &port);
 506     family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
 507         AF_INET : AF_INET6;
 508     JNU_CHECK_EXCEPTION_RETURN(env, -1);
 509     if (family == AF_INET) { /* this API can't handle IPV6 addresses */
 510         int address = getInetAddress_addr(env, iaObj);


 597         }
 598         fullPacket = (char *)malloc(packetBufferLen);
 599 
 600         if (!fullPacket) {
 601             JNU_ThrowOutOfMemoryError(env, "Peek buffer native heap allocation failed");
 602             return -1;
 603         } else {
 604             mallocedPacket = JNI_TRUE;
 605         }
 606     } else {
 607         fullPacket = &(BUF[0]);
 608     }
 609 
 610     n = NET_RecvFrom(fd, fullPacket, packetBufferLen, MSG_PEEK,
 611                      &rmtaddr.sa, &slen);
 612     /* truncate the data if the packet's length is too small */
 613     if (n > packetBufferLen) {
 614         n = packetBufferLen;
 615     }
 616     if (n == -1) {








 617         (*env)->SetIntField(env, packet, dp_offsetID, 0);
 618         (*env)->SetIntField(env, packet, dp_lengthID, 0);
 619         if (errno == ECONNREFUSED) {
 620             JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
 621                             "ICMP Port Unreachable");
 622         } else {
 623             if (errno == EBADF) {
 624                  JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
 625             } else {
 626                  JNU_ThrowByNameWithMessageAndLastError
 627                      (env, JNU_JAVANETPKG "SocketException", "Receive failed");
 628             }
 629         }
 630     } else {
 631         /*
 632          * success - fill in received address...
 633          *
 634          * REMIND: Fill in an int on the packet, and create inetadd
 635          * object in Java, as a performance improvement. Also
 636          * construct the inetadd object lazily.


< prev index next >