1 /*
   2  * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  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 
  26 #include <stdio.h>
  27 #ifdef _WIN32
  28 #include <winsock2.h>
  29 #include <ws2tcpip.h>
  30 #else
  31 #include <sys/types.h>
  32 #include <sys/socket.h>
  33 #include <netinet/in.h>
  34 #include <netinet/tcp.h>
  35 #endif
  36 
  37 /* Defines SO_REUSEPORT */
  38 #if !defined(SO_REUSEPORT)
  39 #ifdef _WIN32
  40 #define SO_REUSEPORT 0
  41 #elif __linux__
  42 #define SO_REUSEPORT 15
  43 #elif __solaris__
  44 #define SO_REUSEPORT 0x100e
  45 #elif defined(AIX) || defined(MACOSX)
  46 #define SO_REUSEPORT 0x0200
  47 #else
  48 #define SO_REUSEPORT 0
  49 #endif
  50 #endif
  51 
  52 /**
  53  * Generates sun.nio.ch.SocketOptionRegistry, a class that maps Java-level
  54  * socket options to the platform specific level and option.
  55  */
  56 
  57 static void out(char* s) {
  58     printf("%s\n", s);
  59 }
  60 
  61 static void emit(const char *name, char * family, int level, int optname) {
  62     printf("            map.put(new RegistryKey(%s, %s),", name, family);
  63     printf(" new OptionKey(%d, %d));\n", level, optname);
  64 }
  65 
  66 static void emit_unspec(const char *name, int level, int optname) {
  67     emit(name, "Net.UNSPEC", level, optname);
  68 }
  69 
  70 static  void emit_inet(const char *name, int level, int optname) {
  71     emit(name, "StandardProtocolFamily.INET", level, optname);
  72 }
  73 
  74 static void emit_inet6(const char *name, int level, int optname) {
  75     emit(name, "StandardProtocolFamily.INET6", level, optname);
  76 }
  77 
  78 int main(int argc, const char* argv[]) {
  79     out("// AUTOMATICALLY GENERATED FILE - DO NOT EDIT                                  ");
  80     out("package sun.nio.ch;                                                            ");
  81     out("import java.net.SocketOption;                                                  ");
  82     out("import java.net.StandardSocketOptions;                                         ");
  83     out("import java.net.ProtocolFamily;                                                ");
  84     out("import java.net.StandardProtocolFamily;                                        ");
  85     out("import java.util.Map;                                                          ");
  86     out("import java.util.HashMap;                                                      ");
  87     out("class SocketOptionRegistry {                                                   ");
  88     out("    private SocketOptionRegistry() { }                                         ");
  89     out("    private static class RegistryKey {                                         ");
  90     out("        private final SocketOption<?> name;                                    ");
  91     out("        private final ProtocolFamily family;                                   ");
  92     out("        RegistryKey(SocketOption<?> name, ProtocolFamily family) {             ");
  93     out("            this.name = name;                                                  ");
  94     out("            this.family = family;                                              ");
  95     out("        }                                                                      ");
  96     out("        public int hashCode() {                                                ");
  97     out("            return name.hashCode() + family.hashCode();                        ");
  98     out("        }                                                                      ");
  99     out("        public boolean equals(Object ob) {                                     ");
 100     out("            if (ob == null) return false;                                      ");
 101     out("            if (!(ob instanceof RegistryKey)) return false;                    ");
 102     out("            RegistryKey other = (RegistryKey)ob;                               ");
 103     out("            if (this.name != other.name) return false;                         ");
 104     out("            if (this.family != other.family) return false;                     ");
 105     out("            return true;                                                       ");
 106     out("        }                                                                      ");
 107     out("    }                                                                          ");
 108     out("    private static class LazyInitialization {                                  ");
 109     out("        static final Map<RegistryKey,OptionKey> options = options();           ");
 110     out("        private static Map<RegistryKey,OptionKey> options() {                  ");
 111     out("            Map<RegistryKey,OptionKey> map =                                   ");
 112     out("                new HashMap<RegistryKey,OptionKey>();                          ");
 113 
 114     emit_unspec("StandardSocketOptions.SO_BROADCAST", SOL_SOCKET, SO_BROADCAST);
 115     emit_unspec("StandardSocketOptions.SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE);
 116     emit_unspec("StandardSocketOptions.SO_LINGER",    SOL_SOCKET, SO_LINGER);
 117     emit_unspec("StandardSocketOptions.SO_SNDBUF",    SOL_SOCKET, SO_SNDBUF);
 118     emit_unspec("StandardSocketOptions.SO_RCVBUF",    SOL_SOCKET, SO_RCVBUF);
 119     emit_unspec("StandardSocketOptions.SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR);
 120     emit_unspec("StandardSocketOptions.SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT);
 121     emit_unspec("StandardSocketOptions.TCP_NODELAY",  IPPROTO_TCP, TCP_NODELAY);
 122 
 123     emit_inet("StandardSocketOptions.IP_TOS",            IPPROTO_IP,     IP_TOS);
 124     emit_inet("StandardSocketOptions.IP_MULTICAST_IF",   IPPROTO_IP,     IP_MULTICAST_IF);
 125     emit_inet("StandardSocketOptions.IP_MULTICAST_TTL",  IPPROTO_IP,     IP_MULTICAST_TTL);
 126     emit_inet("StandardSocketOptions.IP_MULTICAST_LOOP", IPPROTO_IP,     IP_MULTICAST_LOOP);
 127 
 128 #ifdef AF_INET6
 129     emit_inet6("StandardSocketOptions.IP_TOS",            IPPROTO_IPV6,  IPV6_TCLASS);
 130     emit_inet6("StandardSocketOptions.IP_MULTICAST_IF",   IPPROTO_IPV6,  IPV6_MULTICAST_IF);
 131     emit_inet6("StandardSocketOptions.IP_MULTICAST_TTL",  IPPROTO_IPV6,  IPV6_MULTICAST_HOPS);
 132     emit_inet6("StandardSocketOptions.IP_MULTICAST_LOOP", IPPROTO_IPV6,  IPV6_MULTICAST_LOOP);
 133 #endif
 134 
 135     emit_unspec("ExtendedSocketOption.SO_OOBINLINE", SOL_SOCKET, SO_OOBINLINE);
 136 
 137     out("            return map;                                                        ");
 138     out("        }                                                                      ");
 139     out("    }                                                                          ");
 140     out("    public static OptionKey findOption(SocketOption<?> name, ProtocolFamily family) { ");
 141     out("        RegistryKey key = new RegistryKey(name, family);                       ");
 142     out("        return LazyInitialization.options.get(key);                            ");
 143     out("    }                                                                          ");
 144     out("}                                                                              ");
 145 
 146     return 0;
 147 }