/* * 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.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.krakenapps.pcap.Protocol; public class TcpSessionTable { private final TcpProtocolMapper mapper; private Map<TcpSessionKey, TcpSessionImpl> map; public TcpSessionTable(TcpProtocolMapper mapper) { this.mapper = mapper; map = new ConcurrentHashMap<TcpSessionKey, TcpSessionImpl>(); } public void openSession(TcpProtocolMapper mapper, TcpSessionKey key, TcpPacket packet) { TcpSessionImpl session = new TcpSessionImpl(mapper); session.setKey(key); session.createClient(packet); map.put(key, session); } public void doEstablish(TcpSessionImpl session, TcpPacket packet, TcpStateUpdater stateUpdater) { if (isCorrectConnection(session, packet)) { if (!session.isRegisterProtocol()) { registerTcpProcessor(session, packet); session.setRegisterProtocol(true); } stateUpdater.updateState(session, packet); if (session.getClientState() == TcpState.ESTABLISHED && session.getServerState() == TcpState.ESTABLISHED) { session.getClient().setLastFrameReceived(1); session.getServer().setLastFrameReceived(1); } } else abnormalClose(packet.getSessionKey()); } public void close(TcpPacket packet) { if(packet == null) return; TcpSessionKey key = packet.getSessionKey(); Protocol protocol = map.get(key).getProtocol(); if (map.containsKey(key)) map.remove(key); Collection<TcpProcessor> processors = mapper.getTcpProcessors(protocol); if (processors == null) return; for (TcpProcessor p : processors) p.onFinish(key); } public void abnormalClose(TcpSessionKey key) { if (map.containsKey(key)) map.remove(key); } public TcpSessionImpl getSession(TcpSessionKey key) { return map.get(key); } public List<TcpSession> getCurrentSessions() { List<TcpSession> sessions = new ArrayList<TcpSession>(map.values()); return sessions; } public boolean isExist(TcpSessionKey key) { return map.containsKey(key); } private boolean isCorrectConnection(TcpSessionImpl session, TcpPacket packet) { TcpState clientState = session.getClientState(); switch (clientState) { case LISTEN: if (packet.getRelativeSeq() == 0 && packet.getDataLength() == 0) return true; else return false; case SYN_SENT: if (packet.getDirection() == TcpDirection.ToServer) { if (packet.getRelativeSeq() == 1 && packet.getRelativeAck() == 1 && packet.getDataLength() == 0) return true; else return false; } else { if (packet.getRelativeSeq() == 0 && packet.getRelativeAck() == 1 && packet.getDataLength() == 0) return true; else return false; } /* Never access this case */ default: return true; } } private void registerTcpProcessor(TcpSessionImpl session, TcpPacket segment) { Protocol protocol = mapper.map(segment); session.registerProtocol(protocol); Collection<TcpProcessor> processors = mapper.getTcpProcessors(protocol); if (processors == null) return; for (TcpProcessor p : processors) { p.onEstablish(segment.getSessionKey()); } } }