/* * Copyright 2010 NCHOVY * * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.krakenapps.pcap.decoder.tcp; import java.util.concurrent.atomic.AtomicInteger; import org.krakenapps.pcap.Protocol; import org.krakenapps.pcap.util.Buffer; import org.krakenapps.pcap.util.ChainBuffer; public class TcpSessionImpl implements TcpSession { private static AtomicInteger LAST_ID = new AtomicInteger(1); private int id; private TcpSessionKey key; private TcpHost client; private TcpHost server; private int clientFirstSeq; private int serverFirstSeq; private TcpStreamOption clientStreamOption; private TcpStreamOption serverStreamOption; private int clientFlags; private int serverFlags; private TcpState clientState; private TcpState serverState; private boolean isRegisterProtocol; private Protocol protocol; private Buffer clientSent; private Buffer serverSent; private WaitQueue clientQueue; private WaitQueue serverQueue; private ApplicationLayerMapper l7Mapper; private int packetCountAfterFin = 0; private int firstFinSeq = -1; private int firstFinAck = -1; public TcpSessionImpl(TcpProtocolMapper mapper) { id = LAST_ID.getAndIncrement(); key = null; clientStreamOption = TcpStreamOption.NORMAL; serverStreamOption = TcpStreamOption.NORMAL; clientState = TcpState.LISTEN; serverState = TcpState.LISTEN; clientSent = new ChainBuffer(); serverSent = new ChainBuffer(); clientQueue = new WaitQueue(); serverQueue = new WaitQueue(); l7Mapper = new ApplicationLayerMapper(mapper); } public int getId() { return id; } public TcpSessionKey getKey() { return key; } public void setKey(TcpSessionKey key) { this.key = key; } public TcpHost getClient() { return client; } public void createClient(TcpPacket packet) { client = new TcpHost(packet); } public TcpHost getServer() { return server; } public void createServer(TcpPacket packet) { server = new TcpHost(packet); } /* constraint: one-time called */ public void setClientFirstSeq(int clientFirstSeq) { this.clientFirstSeq = clientFirstSeq; } public int retRelativeClientSeq(int sequenceNumber) { return (sequenceNumber - clientFirstSeq); } /* constraint: one-time called */ public void setServerFirstSeq(int serverFirstSeq) { this.serverFirstSeq = serverFirstSeq; } public int retRelativeServerSeq(int sequenceNumber) { return (sequenceNumber - serverFirstSeq); } public TcpStreamOption getClientStreamOption() { return clientStreamOption; } public void setClientStreamOption(TcpStreamOption clientStreamOption) { this.clientStreamOption = clientStreamOption; } public TcpStreamOption getServerStreamOption() { return serverStreamOption; } public void setServerStreamOption(TcpStreamOption serverStreamOption) { this.serverStreamOption = serverStreamOption; } public int getClientFlags() { return clientFlags; } public void setClientFlags(int clientFlags) { this.clientFlags = clientFlags; } public int getServerFlags() { return serverFlags; } public void setServerFlags(int serverFlags) { this.serverFlags = serverFlags; } public TcpState getClientState() { return clientState; } public void setClientState(TcpState clientState) { this.clientState = clientState; } public TcpState getServerState() { return serverState; } public void setServerState(TcpState serverState) { this.serverState = serverState; } public boolean isRegisterProtocol() { return isRegisterProtocol; } public void setRegisterProtocol(boolean isRegisterProtocol) { this.isRegisterProtocol = isRegisterProtocol; } public void registerProtocol(Protocol protocol) { this.protocol = protocol; } public void unregisterProtocol(Protocol protocol) { if (this.protocol == protocol) this.protocol = null; } public Protocol getProtocol() { return protocol; } public void storeToClientSent(Buffer data) { clientSent.addLast(data); } public void storeToServerSent(Buffer data) { serverSent.addLast(data); } public void pushToClient(Buffer data) { l7Mapper.sendToApplicationLayer(protocol, key, TcpDirection.ToClient, data); } public void pushToServer(Buffer data) { l7Mapper.sendToApplicationLayer(protocol, key, TcpDirection.ToServer, data); } public void pushToClientSack(Buffer data) { l7Mapper.sendToApplicationLayer(protocol, key, TcpDirection.ToServer, data); } public void pushToServerSack(Buffer data) { l7Mapper.sendToApplicationLayer(protocol, key, TcpDirection.ToClient, data); } public WaitQueue getClientQueue() { return clientQueue; } public WaitQueue getServerQueue() { return serverQueue; } public int getPacketCountAfterFin() { return packetCountAfterFin; } public void setPacketCountAfterFin(int packetCountAfterFin) { this.packetCountAfterFin = packetCountAfterFin; } public int getFirstFinSeq() { return firstFinSeq; } public void setFirstFinSeq(int firstFinSeq) { this.firstFinSeq = firstFinSeq; } public int getFirstFinAck() { return firstFinAck; } public void setFirstFinAck(int firstFinAck) { this.firstFinAck = firstFinAck; } public void doEstablish(TcpSessionTable sessionTable, TcpSessionImpl session, TcpPacket packet, TcpStateUpdater stateUpdater) { sessionTable.doEstablish(session, packet, stateUpdater); } public void close(TcpSessionTable sessionTable, TcpSessionImpl session, TcpPacket packet) { sessionTable.close(packet); } public void setRelativeNumbers(TcpPacket packet) { switch (packet.getFlags()) { case TcpFlag.SYN: packet.setRelativeSeq(0); break; case TcpFlag.SYN + TcpFlag.ACK: packet.setRelativeSeq(0); packet.setRelativeAck(1); break; default: if (packet.getDirection() == TcpDirection.ToServer) { packet.setRelativeSeq(retRelativeClientSeq(packet.getSeq())); packet.setRelativeAck(retRelativeServerSeq(packet.getAck())); } else { packet.setRelativeSeq(retRelativeServerSeq(packet.getSeq())); packet.setRelativeAck(retRelativeClientSeq(packet.getAck())); } break; } } }