2736N/A/*
3261N/A * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2736N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2736N/A *
2736N/A * This code is free software; you can redistribute it and/or modify it
2736N/A * under the terms of the GNU General Public License version 2 only, as
2736N/A * published by the Free Software Foundation. Oracle designates this
2736N/A * particular file as subject to the "Classpath" exception as provided
2736N/A * by Oracle in the LICENSE file that accompanied this code.
2736N/A *
2736N/A * This code is distributed in the hope that it will be useful, but WITHOUT
2736N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2736N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2736N/A * version 2 for more details (a copy is included in the LICENSE file that
2736N/A * accompanied this code).
2736N/A *
2736N/A * You should have received a copy of the GNU General Public License version
2736N/A * 2 along with this work; if not, write to the Free Software Foundation,
2736N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2736N/A *
2736N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2736N/A * or visit www.oracle.com if you need additional information or have any
2736N/A * questions.
2736N/A */
2736N/A
2736N/A#include <sys/types.h>
2736N/A#include <sys/socket.h>
2736N/A#include <errno.h>
2736N/A
2736N/A#if defined(__solaris__)
2736N/A #if !defined(PROTO_SDP)
2736N/A #define PROTO_SDP 257
2736N/A #endif
2736N/A#elif defined(__linux__)
2736N/A #if !defined(AF_INET_SDP)
2736N/A #define AF_INET_SDP 27
2736N/A #endif
2736N/A#endif
2736N/A
2736N/A#include "jni.h"
2736N/A#include "jni_util.h"
2736N/A#include "net_util.h"
2736N/A
2736N/A#define RESTARTABLE(_cmd, _result) do { \
2736N/A do { \
2736N/A _result = _cmd; \
2736N/A } while((_result == -1) && (errno == EINTR)); \
2736N/A} while(0)
2736N/A
2736N/A
2736N/A/**
2736N/A * Creates a SDP socket.
2736N/A */
2736N/Astatic int create(JNIEnv* env)
2736N/A{
2736N/A int s;
2736N/A
2736N/A#if defined(__solaris__)
2736N/A #ifdef AF_INET6
2736N/A int domain = ipv6_available() ? AF_INET6 : AF_INET;
2736N/A #else
2736N/A int domain = AF_INET;
2736N/A #endif
2736N/A s = socket(domain, SOCK_STREAM, PROTO_SDP);
2736N/A#elif defined(__linux__)
2736N/A /**
2736N/A * IPv6 not supported by SDP on Linux
2736N/A */
2736N/A if (ipv6_available()) {
2736N/A JNU_ThrowIOException(env, "IPv6 not supported");
2884N/A return -1;
2736N/A }
2736N/A s = socket(AF_INET_SDP, SOCK_STREAM, 0);
2736N/A#else
2736N/A /* not supported on other platforms at this time */
2736N/A s = -1;
2736N/A errno = EPROTONOSUPPORT;
2736N/A#endif
2736N/A
2736N/A if (s < 0)
2736N/A JNU_ThrowIOExceptionWithLastError(env, "socket");
2736N/A return s;
2736N/A}
2736N/A
2736N/A/**
2736N/A * Creates a SDP socket, returning file descriptor referencing the socket.
2736N/A */
2736N/AJNIEXPORT jint JNICALL
2736N/AJava_sun_net_sdp_SdpSupport_create0(JNIEnv *env, jclass cls)
2736N/A{
2736N/A return create(env);
2736N/A}
2736N/A
2736N/A/**
2736N/A * Converts an existing file descriptor, that references an unbound TCP socket,
2736N/A * to SDP.
2736N/A */
2736N/AJNIEXPORT void JNICALL
2736N/AJava_sun_net_sdp_SdpSupport_convert0(JNIEnv *env, jclass cls, int fd)
2736N/A{
2736N/A int s = create(env);
2736N/A if (s >= 0) {
2736N/A socklen_t len;
2736N/A int arg, res;
2736N/A struct linger linger;
2736N/A
2736N/A /* copy socket options that are relevant to SDP */
2736N/A len = sizeof(arg);
2736N/A if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, &len) == 0)
2736N/A setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, len);
2736N/A len = sizeof(arg);
2736N/A if (getsockopt(fd, SOL_SOCKET, SO_OOBINLINE, (char*)&arg, &len) == 0)
2736N/A setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char*)&arg, len);
2736N/A len = sizeof(linger);
2736N/A if (getsockopt(fd, SOL_SOCKET, SO_LINGER, (void*)&linger, &len) == 0)
2736N/A setsockopt(s, SOL_SOCKET, SO_LINGER, (char*)&linger, len);
2736N/A
2736N/A RESTARTABLE(dup2(s, fd), res);
2736N/A if (res < 0)
2736N/A JNU_ThrowIOExceptionWithLastError(env, "dup2");
2736N/A RESTARTABLE(close(s), res);
2736N/A }
2736N/A}