Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
BEGIN LICENSE BLOCK ***** Version: EPL 1.0/GPL 2.0/LGPL 2.1 The contents of this file are subject to the Eclipse Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.eclipse.org/legal/epl-v10.html Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Alternatively, the contents of this file may be used under the terms of either of the GNU General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the LGPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of either the GPL or the LGPL, and not to allow others to use your version of this file under the terms of the EPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL or the LGPL. If you do not delete the provisions above, a recipient may use your version of this file under the terms of any one of the EPL, the GPL or the LGPL. END LICENSE BLOCK ***
 
 
 package org.jruby.ext.socket;
 
 import org.jruby.Ruby;
 
 import java.util.List;
 
 import static jnr.constants.platform.AddressFamily.AF_INET;
 import static jnr.constants.platform.IPProto.IPPROTO_TCP;
 import static jnr.constants.platform.IPProto.IPPROTO_UDP;
 import static jnr.constants.platform.NameInfo.NI_NUMERICHOST;
 import static jnr.constants.platform.NameInfo.NI_NUMERICSERV;
 import static jnr.constants.platform.ProtocolFamily.PF_INET;
 import static jnr.constants.platform.ProtocolFamily.PF_INET6;
 import static jnr.constants.platform.Sock.SOCK_DGRAM;
 import static jnr.constants.platform.Sock.SOCK_STREAM;
Socket class methods for addresses, structures, and so on.
 
 public class SocketUtils {
     public static IRubyObject gethostname(ThreadContext context) {
         Ruby runtime = context.runtime;
 
         try {
             return runtime.newString(InetAddress.getLocalHost().getHostName());
 
         } catch(UnknownHostException e) {
 
             try {
                 return runtime.newString(InetAddress.getByAddress(new byte[]{0,0,0,0}).getHostName());
 
             } catch(UnknownHostException e2) {
                 throw sockerr(runtime"gethostname: name or service not known");
 
             }
         }
     }
 
     public static IRubyObject gethostbyaddr(ThreadContext contextIRubyObject[] args) {
         Ruby runtime = context.runtime;
         IRubyObject[] ret = new IRubyObject[4];
 
         ret[0] = runtime.newString(Sockaddr.addressFromString(runtimeargs[0].convertToString().toString()).getCanonicalHostName());
         ret[1] = runtime.newArray();
         ret[2] = runtime.newFixnum(2); // AF_INET
         ret[3] = args[0];
 
        return runtime.newArrayNoCopy(ret);
    }
    public static IRubyObject getservbyname(ThreadContext contextIRubyObject[] args) {
        Ruby runtime = context.runtime;
        String name = args[0].convertToString().toString();
        String proto = args.length ==  1 ? "tcp" : args[1].convertToString().toString();
        Service service = Service.getServiceByName(nameproto);
        int port;
        if (service != null) {
            port = service.getPort();
        } else {
            // MRI behavior: try to convert the name string to port directly
            try {
                port = Integer.parseInt(name.trim());
            } catch (NumberFormatException nfe) {
                throw sockerr(runtime"no such service " + name + "/" + proto);
            }
        }
        return runtime.newFixnum(port);
    }
    public static IRubyObject pack_sockaddr_in(ThreadContext contextIRubyObject portIRubyObject host) {
        int portNum = port instanceof RubyString ?
                Integer.parseInt(port.convertToString().toString()) :
                RubyNumeric.fix2int(port);
        return Sockaddr.pack_sockaddr_in(
                context,
                portNum,
                host.isNil() ? null : host.convertToString().toString());
    }
    public static IRubyObject unpack_sockaddr_in(ThreadContext contextIRubyObject addr) {
        return Sockaddr.unpack_sockaddr_in(contextaddr);
    }
    public static IRubyObject pack_sockaddr_un(ThreadContext contextIRubyObject filename) {
        ByteList str = filename.convertToString().getByteList();
        AddressFamily af = .;
        int high = (af.intValue() & 0xff00) >> 8;
        int low = af.intValue() & 0xff;
        ByteList bl = new ByteList();
        bl.append((byte)high);
        bl.append((byte)low);
        bl.append(str);
        for(int i=str.length();i<104;i++) {
            bl.append((byte)0);
        }
        return context.runtime.newString(bl);
    }
    public static IRubyObject gethostbyname(ThreadContext contextIRubyObject hostname) {
        Ruby runtime = context.runtime;
        try {
            InetAddress addr = getRubyInetAddress(hostname.convertToString().getByteList());
            IRubyObject[] ret = new IRubyObject[4];
            ret[0] = runtime.newString(addr.getCanonicalHostName());
            ret[1] = runtime.newArray();
            ret[2] = runtime.newFixnum(2); // AF_INET
            ret[3] = runtime.newString(new ByteList(addr.getAddress()));
            return runtime.newArrayNoCopy(ret);
        } catch(UnknownHostException e) {
            throw sockerr(runtime"gethostbyname: name or service not known");
        }
    }

    
Ruby definition would look like: def self.getaddrinfo(host, port, family = nil, socktype = nil, protocol = nil, flags = nil)
    public static IRubyObject getaddrinfo(final ThreadContext contextIRubyObject[] args) {
        final Ruby runtime = context.runtime;
        final List<IRubyObjectl = new ArrayList<IRubyObject>();
        buildAddrinfoList(contextargsnew AddrinfoCallback() {
            @Override
            public void addrinfo(InetAddress addressint portSock sock) {
                boolean is_ipv6 = address instanceof Inet6Address;
                boolean sock_stream = true;
                boolean sock_dgram = true;
                if (sock != null) {
                    if (sock == ) {
                        sock_dgram = false;
                    } else if (sock == ) {
                        sock_stream = false;
                    }
                }
                IRubyObject[] c;
                if (sock_dgram) {
                    c = new IRubyObject[7];
                    c[0] = runtime.newString(is_ipv6 ? "AF_INET6" : "AF_INET");
                    c[1] = runtime.newFixnum(port);
                    c[2] = runtime.newString(getHostAddress(contextaddress));
                    c[3] = runtime.newString(address.getHostAddress());
                    c[4] = runtime.newFixnum(is_ipv6 ?  : );
                    c[5] = runtime.newFixnum();
                    c[6] = runtime.newFixnum();
                    l.add(runtime.newArrayNoCopy(c));
                }
                if (sock_stream) {
                    c = new IRubyObject[7];
                    c[0] = runtime.newString(is_ipv6 ? "AF_INET6" : "AF_INET");
                    c[1] = runtime.newFixnum(port);
                    c[2] = runtime.newString(getHostAddress(contextaddress));
                    c[3] = runtime.newString(address.getHostAddress());
                    c[4] = runtime.newFixnum(is_ipv6 ?  : );
                    c[5] = runtime.newFixnum();
                    c[6] = runtime.newFixnum();
                    l.add(runtime.newArrayNoCopy(c));
                }
            }
        });
        return runtime.newArray(l);
    }
    public static List<AddrinfogetaddrinfoList(ThreadContext contextIRubyObject[] args) {
        final Ruby runtime = context.runtime;
        final List<Addrinfol = new ArrayList<Addrinfo>();
        buildAddrinfoList(contextargsnew AddrinfoCallback() {
            @Override
            public void addrinfo(InetAddress addressint portSock sock) {
                boolean sock_stream = true;
                boolean sock_dgram = true;
                if (sock != null) {
                    if (sock == ) {
                        sock_dgram = false;
                    } else if (sock == ) {
                        sock_stream = false;
                    }
                }
                if (sock_dgram) {
                    l.add(new Addrinfo(runtimeruntime.getClass("Addrinfo"),
                            address,
                            port,
                            .));
                }
                if (sock_stream) {
                    l.add(new Addrinfo(runtimeruntime.getClass("Addrinfo"),
                            address,
                            port,
                            .));
                }
            }
        });
        return l;
    }
    interface AddrinfoCallback {
        void addrinfo(
                InetAddress address,
                int port,
                Sock sock);
    }
    public static void buildAddrinfoList(ThreadContext contextIRubyObject[] argsAddrinfoCallback callback) {
        Ruby runtime = context.runtime;
        IRubyObject host = args[0];
        IRubyObject port = args[1];
        boolean emptyHost = host.isNil() || host.convertToString().isEmpty();
        try {
            if(port instanceof RubyString) {
                port = getservbyname(contextnew IRubyObject[]{port});
            }
            IRubyObject family = args.length > 2 ? args[2] : context.nil;
            IRubyObject socktype = args.length > 3 ? args[3] : context.nil;
            //IRubyObject protocol = args[4];
            IRubyObject flags = args.length > 5 ? args[5] : context.nil;
            AddressFamily addressFamily = ;
            if (!family.isNil()) {
                addressFamily = addressFamilyFromArg(family);
            }
            boolean is_ipv6 = addressFamily == .;
            boolean sock_stream = true;
            boolean sock_dgram = true;
            Sock sock = ;
            if(!socktype.isNil()) {
                sockFromArg(socktype);
                if(sock == ) {
                    sock_dgram = false;
                } else if (sock == ) {
                    sock_stream = false;
                }
            }
            // When Socket::AI_PASSIVE and host is nil, return 'any' address.
            InetAddress[] addrs = null;
            if(!flags.isNil() && RubyFixnum.fix2int(flags) > 0) {
                // The value of 1 is for Socket::AI_PASSIVE.
                int flag = RubyNumeric.fix2int(flags);
                if ((flag == 1) && emptyHost ) {
                    // use RFC 2732 style string to ensure that we get Inet6Address
                    addrs = InetAddress.getAllByName(is_ipv6 ? "[::]" : "0.0.0.0");
                }
            }
            if (addrs == null) {
                addrs = InetAddress.getAllByName(emptyHost ? (is_ipv6 ? "[::1]" : null) : host.convertToString().toString());
            }
            for(int i = 0; i < addrs.lengthi++) {
                int p = port.isNil() ? 0 : (int)port.convertToInteger().getLongValue();
                callback.addrinfo(addrs[i], psock);
            }
        } catch(UnknownHostException e) {
            throw sockerr(runtime"getaddrinfo: name or service not known");
        }
    }
    public static IRubyObject getnameinfo(ThreadContext contextIRubyObject[] args) {
        Ruby runtime = context.runtime;
        int flags = args.length == 2 ? RubyNumeric.num2int(args[1]) : 0;
        IRubyObject arg0 = args[0];
        String hostport;
        if (arg0 instanceof RubyArray) {
            List list = ((RubyArray)arg0).getList();
            int len = list.size();
            if (len < 3 || len > 4) {
                throw runtime.newArgumentError("array size should be 3 or 4, "+len+" given");
            }
            // if array has 4 elements, third element is ignored
            host = list.size() == 3 ? list.get(2).toString() : list.get(3).toString();
            port = list.get(1).toString();
        } else if (arg0 instanceof RubyString) {
            String arg = ((RubyString)arg0).toString();
            Matcher m = .matcher(arg);
            if (!m.matches()) {
                IRubyObject obj = unpack_sockaddr_in(contextarg0);
                if (obj instanceof RubyArray) {
                    List list = ((RubyArray)obj).getList();
                    int len = list.size();
                    if (len != 2) {
                        throw runtime.newArgumentError("invalid address representation");
                    }
                    host = list.get(1).toString();
                    port = list.get(0).toString();
                } else {
                    throw runtime.newArgumentError("invalid address string");
                }
            } else if ((host = m.group()) == null || host.length() == 0 ||
                    (port = m.group()) == null || port.length() == 0) {
                throw runtime.newArgumentError("invalid address string");
            } else {
                // Try IPv6
                try {
                    InetAddress ipv6_addr = InetAddress.getByName(host);
                    if (ipv6_addr instanceof Inet6Address) {
                        host = ipv6_addr.getHostAddress();
                    }
                } catch (UnknownHostException uhe) {
                    throw runtime.newArgumentError("invalid address string");
                }
            }
        } else {
            throw runtime.newArgumentError("invalid args");
        }
        InetAddress addr;
        try {
            addr = InetAddress.getByName(host);
        } catch (UnknownHostException e) {
            throw sockerr(runtime"unknown host: "host);
        }
        if ((flags & .intValue()) == 0) {
            host = addr.getCanonicalHostName();
        } else {
            host = addr.getHostAddress();
        }
        jnr.netdb.Service serv = jnr.netdb.Service.getServiceByPort(Integer.parseInt(port), null);
        if (serv != null) {
            if ((flags & .intValue()) == 0) {
                port = serv.getName();
            } else {
                port = Integer.toString(serv.getPort());
            }
        }
        return runtime.newArray(runtime.newString(host), runtime.newString(port));
    }
    public static IRubyObject ip_address_list(ThreadContext context) {
        Ruby runtime = context.runtime;
        try {
            RubyArray list = RubyArray.newArray(runtime);
            RubyClass addrInfoCls = runtime.getClass("Addrinfo");
            for (Enumeration<NetworkInterfacenetworkIfcs = NetworkInterface.getNetworkInterfaces() ; networkIfcs.hasMoreElements() ; ) {
                for (Enumeration<InetAddressaddresses = networkIfcs.nextElement().getInetAddresses() ; addresses.hasMoreElements() ; ) {
                    list.append(new Addrinfo(runtimeaddrInfoClsaddresses.nextElement()));
                }
            }
            return list;
        } catch (SocketException se) {
            throw sockerr(runtimese.getLocalizedMessage());
        }
    }
    public static InetAddress getRubyInetAddress(ByteList addressthrows UnknownHostException {
        // switched to String because the ByteLists were not comparing properly in 1.9 mode (encoding?
        // FIXME: Need to properly decode this string (see Helpers.decodeByteList)
        String addressString = Helpers.byteListToString(address);
        if (addressString.equals()) {
            return InetAddress.getByAddress();
        } else if (addressString.equals()) {
            return InetAddress.getByAddress();
        } else {
            return InetAddress.getByName(addressString);
        }
    }
    public static IRubyObject getaddress(ThreadContext contextIRubyObject hostname) {
        try {
            return context.runtime.newString(InetAddress.getByName(hostname.convertToString().toString()).getHostAddress());
        } catch(UnknownHostException e) {
            throw sockerr(context.runtime"getaddress: name or service not known");
        }
    }
    public static RuntimeException sockerr(Ruby runtimeString msg) {
        return new RaiseException(runtimeruntime.getClass("SocketError"), msgtrue);
    }
    public static int getPortFrom(ThreadContext contextIRubyObject _port) {
        int port;
        if (_port instanceof RubyInteger) {
            port = RubyNumeric.fix2int(_port);
        } else {
            IRubyObject portString = _port.convertToString();
            IRubyObject portInteger = portString.convertToInteger"to_i");
            port = RubyNumeric.fix2int(portInteger);
            if (port <= 0) {
                port = RubyNumeric.fix2int(RubySocket.getservbyname(
                        contextcontext.runtime.getObject(), new IRubyObject[]{portString}));
            }
        }
        return port;
    }
    private static String getHostAddress(ThreadContext contextInetAddress addr) {
        return context.runtime.isDoNotReverseLookupEnabled() ? addr.getHostAddress() : addr.getCanonicalHostName();
    }
    private static final Pattern STRING_IPV4_ADDRESS_PATTERN =
            Pattern.compile("((.*)\\/)?([\\.0-9]+)(:([0-9]+))?");
    private static final int IPV4_HOST_GROUP = 3;
    private static final int IPV4_PORT_GROUP = 5;
    private static final String BROADCAST = "<broadcast>";
    private static final byte[] INADDR_BROADCAST = new byte[] {-1,-1,-1,-1}; // 255.255.255.255
    private static final String ANY = "<any>";
    private static final byte[] INADDR_ANY = new byte[] {0,0,0,0}; // 0.0.0.0
        AddressFamily addressFamily = null;
        if(domain instanceof RubyString || domain instanceof RubySymbol) {
            String domainString = domain.toString();
            if (!domainString.startsWith("AF_")) domainString = "AF_" + domainString;
            addressFamily = AddressFamily.valueOf(domainString);
        } else {
            int domainInt = RubyNumeric.fix2int(domain);
            addressFamily = AddressFamily.valueOf(domainInt);
        }
        return addressFamily;
    }
    static Sock sockFromArg(IRubyObject type) {
        Sock sockType = null;
        if(type instanceof RubyString || type instanceof RubySymbol) {
            String typeString = type.toString();
            sockType = Sock.valueOf("SOCK_" + typeString);
        } else {
            int typeInt = RubyNumeric.fix2int(type);
            sockType = Sock.valueOf(typeInt);
        }
        return sockType;
    }
    static ProtocolFamily protocolFamilyFromArg(IRubyObject protocol) {
        ProtocolFamily protocolFamily = null;
        if(protocol instanceof RubyString || protocol instanceof RubySymbol) {
            String protocolString = protocol.toString();
            protocolFamily = ProtocolFamily.valueOf("PF_" + protocolString);
        } else {
            int protocolInt = RubyNumeric.fix2int(protocol);
            if (protocolInt == 0) return null;
            protocolFamily = ProtocolFamily.valueOf(protocolInt);
        }
        return protocolFamily;
    }
    
    public static int portToInt(IRubyObject port) {
        return port.isNil() ? 0 : RubyNumeric.fix2int(port);
    }
New to GrepCode? Check out our FAQ X