org.opendaylight.usc.crypto.dtls.DtlsEngine.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.usc.crypto.dtls.DtlsEngine.java

Source

/*
 * Copyright (c) 2015 Huawei, Inc and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */

package org.opendaylight.usc.crypto.dtls;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.socket.DatagramPacket;

import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.LinkedBlockingQueue;

import org.bouncycastle.crypto.tls.DTLSTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DtlsEngine {

    private static final Logger log = LoggerFactory.getLogger(DtlsEngine.class);

    private DTLSTransport encTransport = null;
    private final DtlsHandlerTransport rawTransport;

    private final LinkedBlockingQueue<DatagramPacket> writeQueue = new LinkedBlockingQueue<>();

    public DtlsEngine(DtlsHandlerTransport rawTransport) {
        this.rawTransport = rawTransport;
    }

    public ArrayList<DatagramPacket> read(DatagramPacket msg)
            throws InterruptedException, ExecutionException, IOException {

        log.trace("DtlsEngine read " + msg);
        // add to queue irrespective of whether initialized or not;
        // this way the protocol handshake can retrieve them
        rawTransport.enqueue(msg);

        ArrayList<DatagramPacket> packets = new ArrayList<>();
        if (encTransport != null) {
            byte buf[] = new byte[encTransport.getReceiveLimit()];
            while (rawTransport.hasPackets()) {
                int bytesRead = encTransport.receive(buf, 0, buf.length, 100);
                if (bytesRead > 0) {
                    packets.add(new DatagramPacket(Unpooled.copiedBuffer(buf, 0, bytesRead),
                            rawTransport.getRemoteAddress()));
                }
            }
        }
        return packets;
    }

    private static void write(DTLSTransport encTransport, DatagramPacket packet) throws IOException {
        ByteBuf byteBuf = packet.content();
        int readableBytes = byteBuf.readableBytes();
        log.trace("DtlsEngine write " + packet);
        byte buf[] = new byte[encTransport.getSendLimit()];
        byteBuf.readBytes(buf, 0, readableBytes);
        byteBuf.release();
        encTransport.send(buf, 0, readableBytes);
    }

    public void write(DatagramPacket packet) throws IOException, InterruptedException, ExecutionException {
        if (encTransport != null) {
            write(encTransport, packet);
        } else {
            writeQueue.add(packet);
        }
    }

    public void initialize(DTLSTransport encTransport)
            throws InterruptedException, ExecutionException, IOException {
        // first send all queued up messages
        ArrayList<DatagramPacket> packets = new ArrayList<>();
        writeQueue.drainTo(packets);
        for (DatagramPacket packet : packets) {
            write(encTransport, packet);
        }

        // expose this to the outside world last to avoid race conditions
        this.encTransport = encTransport;
    }

    public boolean isInitialized() {
        return encTransport != null;
    }

}