Package io.nodyn.tcp

Source Code of io.nodyn.tcp.UnsafeTcp$BoundField

package io.nodyn.tcp;

import io.netty.channel.socket.SocketChannelConfig;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.nodyn.fs.UnsafeFs;

import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;

/**
* @author Bob McWhirter
*/
public class UnsafeTcp {

    private static class BoundField {

        BoundField(Object object, Field field) {
            this.object = object;
            this.field = field;
        }

        Object get() throws IllegalAccessException {
            return this.field.get( this.object );
        }

        int getInt() throws IllegalAccessException {
            return this.field.getInt( this.object );
        }

        void setInt(int value) throws IllegalAccessException {
            this.field.setInt( this.object, value );
        }

        Object object;
        Field field;
    }

    private static BoundField getField(Object obj, String fieldName) {
        return getField(obj, obj.getClass(), fieldName);
    }

    private static BoundField getField(Object obj, Class cls, String fieldName) {
        try {
            Field f = cls.getDeclaredField(fieldName);
            if (f != null) {
                f.setAccessible(true);
                return new BoundField( obj, f );
            }
        } catch (NoSuchFieldException e) {
            // ignore, try superclass
        }
        if (cls.getSuperclass() == null) {
            return null;
        }
        return getField(obj, cls.getSuperclass(), fieldName);
    }

    private static BoundField getDeepField(Object obj, String... fieldNames) {
        Object cur = obj;

        for (int i = 0; i < fieldNames.length - 1; ++i) {
            BoundField f = getField(cur, fieldNames[i]);
            if (f == null) {
                return null;
            }
            try {
                cur = f.get();
            } catch (IllegalAccessException e) {
                return null;
            }

            if (cur == null) {
                return null;
            }
        }

        return getField(cur, fieldNames[fieldNames.length - 1]);
    }

    public static int getFd(NioSocketChannel channel) throws NoSuchFieldException, IllegalAccessException, IOException {

        SocketChannelConfig config = channel.config();

        BoundField f = getField( config, "javaSocket" );
        Socket socket = (Socket) f.get();

        InputStream in = socket.getInputStream();
        f = getDeepField(in, "ch", "fd", "fd");

        if (f == null) {
            return -1;
        }

        return f.getInt();
    }

    public static SocketChannel attach(int fd) throws Exception {
        Class<?> cls = UnsafeTcp.class.getClassLoader().loadClass("sun.nio.ch.SocketChannelImpl");

        Constructor<?> ctor = cls.getDeclaredConstructor(SelectorProvider.class, FileDescriptor.class, InetSocketAddress.class);

        SelectorProvider provider = SelectorProvider.provider();
        FileDescriptor fileDesc = UnsafeFs.createFileDescriptor( fd );

        ctor.setAccessible(true);
        SocketChannel socketChannel = (SocketChannel) ctor.newInstance(provider, fileDesc, null);

        return socketChannel;
    }

    private static void dump(Object o) throws IllegalAccessException {
        dump("", o, o.getClass());
    }

    private static void dump(String indent, Object o, Class cls) throws IllegalAccessException {
        System.err.println(indent + ">" + cls.getName());
        Field[] fields = cls.getDeclaredFields();
        for (int i = 0; i < fields.length; ++i) {
            fields[i].setAccessible(true);
            Object v = fields[i].get(o);
            System.err.println(indent + "  - " + fields[i].getName() + " = " + v + (v == null ? "" : " (" + v.getClass().getName() + ")"));
        }

        if (cls.getSuperclass() != null) {
            dump(indent + "  ", o, cls.getSuperclass());
        }
    }
}
TOP

Related Classes of io.nodyn.tcp.UnsafeTcp$BoundField

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.