use of com.att.aro.core.packetreader.pojo.TCPPacket in project VideoOptimzer by attdevsupport.
the class UnsecureSSLVersionImplTest method getPacketAnalyzerResult.
private PacketAnalyzerResult getPacketAnalyzerResult(Set<String> unsecureSSLVersions) {
Session session = mock(Session.class);
PacketInfo info = mock(PacketInfo.class);
TCPPacket tcpPacket = mock(TCPPacket.class);
InetAddress address = mock(InetAddress.class);
String ipAddress = "127.0.0.1";
int port = 8080;
List<Session> sessions = new ArrayList<>();
sessions.add(session);
List<PacketInfo> packetInfos = new LinkedList<>();
packetInfos.add(info);
packetAnalyzerResult.setSessionlist(sessions);
when(session.getTcpPackets()).thenReturn(packetInfos);
when(info.getPacket()).thenReturn(tcpPacket);
when(tcpPacket.getUnsecureSSLVersions()).thenReturn(unsecureSSLVersions);
when(address.getHostAddress()).thenReturn(ipAddress);
when(session.getRemoteIP()).thenReturn(address);
when(session.getRemotePort()).thenReturn(port);
return packetAnalyzerResult;
}
use of com.att.aro.core.packetreader.pojo.TCPPacket in project VideoOptimzer by attdevsupport.
the class SessionManagerImpl method analyzeRecoverPkts.
/**
* Analyze the packet to find the TCPInfo. Marked flags: TCP_DATA_RECOVER,
* TCP_ACK_RECOVER
*/
private void analyzeRecoverPkts(Session sess) {
// "Recover data": its seq equals to the duplicated ACK
// "Recover ack": its ack equals to the duplicated DATA + payload len
Map<Long, TCPPacket> dupAckUl = new HashMap<Long, TCPPacket>();
Map<Long, TCPPacket> dupAckDl = new HashMap<Long, TCPPacket>();
Map<Long, TCPPacket> dupSeqUl = new HashMap<Long, TCPPacket>();
Map<Long, TCPPacket> dupSeqDl = new HashMap<Long, TCPPacket>();
for (PacketInfo pInfo : sess.getTcpPackets()) {
TCPPacket tPacket = (TCPPacket) pInfo.getPacket();
TcpInfo pType = pInfo.getTcpInfo();
PacketDirection dir = pInfo.getDir();
if (pType == TcpInfo.TCP_DATA_DUP) {
if (dir == PacketDirection.UPLINK) {
dupSeqUl.put(tPacket.getSequenceNumber() + tPacket.getPayloadLen(), tPacket);
} else {
dupSeqDl.put(tPacket.getSequenceNumber() + tPacket.getPayloadLen(), tPacket);
}
}
// Duplicated data means duplicated ack as well
if (pType == TcpInfo.TCP_ACK_DUP || pType == TcpInfo.TCP_DATA_DUP) {
if (dir == PacketDirection.UPLINK) {
dupAckUl.put(tPacket.getAckNumber(), tPacket);
} else {
dupAckDl.put(tPacket.getAckNumber(), tPacket);
}
}
if (pType == TcpInfo.TCP_DATA) {
if (dir == PacketDirection.UPLINK && dupAckDl.containsKey(tPacket.getSequenceNumber())) {
pInfo.setTcpInfo(TcpInfo.TCP_DATA_RECOVER);
}
if (dir == PacketDirection.DOWNLINK && dupAckUl.containsKey(tPacket.getSequenceNumber())) {
pInfo.setTcpInfo(TcpInfo.TCP_DATA_RECOVER);
}
}
if (pType == TcpInfo.TCP_ACK) {
if (dir == PacketDirection.UPLINK && dupSeqDl.containsKey(tPacket.getAckNumber())) {
pInfo.setTcpInfo(TcpInfo.TCP_DATA_RECOVER);
}
if (dir == PacketDirection.DOWNLINK && dupSeqUl.containsKey(tPacket.getAckNumber())) {
pInfo.setTcpInfo(TcpInfo.TCP_DATA_RECOVER);
}
}
// UL: TCP_DATA with seq = 1 <==== This is NOT a DATA_RECOVER
if (pType == TcpInfo.TCP_ACK || pType == TcpInfo.TCP_ACK_DUP || pType == TcpInfo.TCP_ACK_RECOVER) {
if (dir == PacketDirection.UPLINK) {
dupAckDl.remove(tPacket.getSequenceNumber());
}
if (dir == PacketDirection.DOWNLINK) {
dupAckUl.remove(tPacket.getSequenceNumber());
}
}
// But vise versa is not true
if (pType == TcpInfo.TCP_DATA || pType == TcpInfo.TCP_DATA_RECOVER) {
if (dir == PacketDirection.UPLINK) {
dupAckUl.remove(tPacket.getAckNumber());
}
if (dir == PacketDirection.DOWNLINK) {
dupAckDl.remove(tPacket.getAckNumber());
}
}
}
}
use of com.att.aro.core.packetreader.pojo.TCPPacket in project VideoOptimzer by attdevsupport.
the class SessionManagerImpl method setFirstAndLastDataPacket.
/**
* Used to set the first and last data packet for secure sessions in iOS.
* The data isn't available from the request and response file, so this method helps with it
* Identified the packet with the time stamp closest to the request time in iOS secure file.
*
* @param results
* @param usedPackets
* @param rrInfo
* @param packetMap
* @param matchKey
*/
private void setFirstAndLastDataPacket(ArrayList<HttpRequestResponseInfo> results, Map<Double, PacketInfo> usedPackets, HttpRequestResponseInfo rrInfo, TreeMap<Double, PacketInfo> packetMap, Map.Entry<Double, PacketInfo> matchKey) {
/**
* Identify the packet closest to the request time stamp in the iOS file
* Assign that as the first and last data packet
*/
if (matchKey != null) {
do {
if (!usedPackets.containsKey(matchKey.getKey()) && ((TCPPacket) matchKey.getValue().getPacket()).getLen() > 0) {
rrInfo.setFirstDataPacket(matchKey.getValue());
rrInfo.setLastDataPacket(matchKey.getValue());
usedPackets.put(matchKey.getKey(), matchKey.getValue());
break;
}
} while ((matchKey = packetMap.higherEntry(matchKey.getKey())) != null);
}
/**
* If a request has a first data packet, then
* the the previous packet with data, if it hasn't been used before,
* is the last data packet for the previous request.
*/
if (results.size() > 0) {
HttpRequestResponseInfo previousRequest = results.get(results.size() - 1);
while (matchKey != null && ((matchKey = packetMap.lowerEntry(matchKey.getKey())) != null) && ((TCPPacket) matchKey.getValue().getPacket()).getLen() > 0) {
if (matchKey.getValue().getTimeStamp() < previousRequest.getTimeStamp()) {
break;
} else if (!usedPackets.containsKey(matchKey.getKey())) {
previousRequest.setLastDataPacket(matchKey.getValue());
break;
}
}
}
}
use of com.att.aro.core.packetreader.pojo.TCPPacket in project VideoOptimzer by attdevsupport.
the class SessionManagerImpl method identifyCorrectTransmissionStream.
/**
* Check and return which packet in the initial packet list by sequence number received the first ACK in the communication
* @param packetInfoListForSequenceNumber Initial packet list by a sequence number
* @param ackNumbersSet Set of all the ACK numbers
* @param session Session object
* @param direction Packet direction Uplink or Downlink
* @return Returns a packet from the packetInfoListForSequenceNumber which has received an ACK in the whole TCP communication.
* Returns the last packet in the list if no ACK is received.
*/
private PacketInfo identifyCorrectTransmissionStream(List<PacketInfo> packetInfoListForSequenceNumber, Set<Long> ackNumbersSet, Session session, PacketDirection direction) {
if (packetInfoListForSequenceNumber.size() == 1) {
return packetInfoListForSequenceNumber.get(0);
}
PacketInfo currentPacket = null;
// Iterate through the parent packet list by sequence number
for (PacketInfo packetInfo : packetInfoListForSequenceNumber) {
currentPacket = packetInfo;
TCPPacket tcpPacket = (TCPPacket) packetInfo.getPacket();
long nextSequenceOrAckNumber = tcpPacket.getSequenceNumber() + tcpPacket.getPayloadLen();
List<PacketInfo> packetInfoListForNextSequenceNumber = PacketDirection.DOWNLINK.equals(direction) ? session.getDownlinkPacketsSortedBySequenceNumbers().get(nextSequenceOrAckNumber) : session.getUplinkPacketsSortedBySequenceNumbers().get(nextSequenceOrAckNumber);
if (ackNumbersSet.contains(nextSequenceOrAckNumber) || identifyCorrectTCPTransmissionStreamHelper(packetInfoListForNextSequenceNumber, ackNumbersSet, session, direction)) {
return currentPacket;
}
}
return currentPacket;
}
use of com.att.aro.core.packetreader.pojo.TCPPacket in project VideoOptimzer by attdevsupport.
the class SessionManagerImpl method analyzeRequestResponses.
/**
* Traverse all Sessions of all types UDP/TCP/
*
* @param sessions
*/
private void analyzeRequestResponses(List<Session> sessions) {
ArrayList<HttpRequestResponseInfo> results;
for (Session session : sessions) {
int limit = 0;
results = new ArrayList<>();
PacketInfo previousPacket = null;
if (session.isUdpOnly()) {
// UDP
HttpRequestResponseInfo rrInfo = null;
HttpRequestResponseInfo recentUpRRInfo = null;
HttpRequestResponseInfo recentDnRRInfo = null;
for (PacketInfo udpPacketInfo : session.getUdpPackets()) {
try {
switch(udpPacketInfo.getDir()) {
case UPLINK:
if (!session.isDataInaccessible()) {
rrInfo = extractHttpRequestResponseInfo(results, session, udpPacketInfo, udpPacketInfo.getDir(), previousPacket, limit);
}
if (rrInfo != null) {
recentUpRRInfo = rrInfo;
} else {
if (443 == session.getLocalPort() || 443 == session.getRemotePort() || 80 == session.getLocalPort() || 80 == session.getRemotePort()) {
session.setDataInaccessible(true);
results = analyzeRequestResponsesForQUICUDPSession(session);
break;
}
if (recentUpRRInfo == null) {
// Creating a Request Objects when no actual requests were found.
session.setDataInaccessible(true);
rrInfo = new HttpRequestResponseInfo(session.getRemoteHostName(), udpPacketInfo.getDir());
populateRRInfo(rrInfo, udpPacketInfo, false, false, HttpDirection.REQUEST);
results.add(rrInfo);
recentUpRRInfo = rrInfo;
}
if (udpPacketInfo.getPayloadLen() != 0) {
updateRequestResponseObject(recentUpRRInfo, udpPacketInfo);
}
}
rrInfo = null;
recentUpRRInfo.writePayload(udpPacketInfo, false, 0);
recentUpRRInfo.addUDPPacket(udpPacketInfo);
break;
case DOWNLINK:
if (!session.isDataInaccessible()) {
rrInfo = extractHttpRequestResponseInfo(results, session, udpPacketInfo, udpPacketInfo.getDir(), previousPacket, limit);
}
if (rrInfo != null) {
recentDnRRInfo = rrInfo;
} else {
if (recentDnRRInfo == null) {
rrInfo = new HttpRequestResponseInfo(session.getRemoteHostName(), udpPacketInfo.getDir());
populateRRInfo(rrInfo, udpPacketInfo, false, false, HttpDirection.RESPONSE);
results.add(rrInfo);
recentDnRRInfo = rrInfo;
}
if (udpPacketInfo.getPayloadLen() != 0) {
updateRequestResponseObject(recentDnRRInfo, udpPacketInfo);
}
}
rrInfo = null;
recentDnRRInfo.writePayload(udpPacketInfo, false, 0);
recentDnRRInfo.addUDPPacket(udpPacketInfo);
break;
default:
LOGGER.warn("91 - No direction for packet");
continue;
}
} catch (IOException e) {
LOGGER.error("Error Storing data to UDP Request Response Obect. Session ID: " + session.getSessionKey());
}
}
} else {
// TCP
analyzeACK(session);
analyzeZeroWindow(session);
analyzeRecoverPkts(session);
PacketInfo packetInfo = null;
TCPPacket tcpPacket = null;
HttpRequestResponseInfo rrInfo = null;
HttpRequestResponseInfo tempRRInfo = null;
try {
long expectedUploadSeqNo = 0;
for (long uploadSequenceNumber : session.getUplinkPacketsSortedBySequenceNumbers().keySet()) {
// Identify correct packet from the whole transmission stream
packetInfo = identifyCorrectTransmissionStream(session.getUplinkPacketsSortedBySequenceNumbers().get(uploadSequenceNumber), session.getAckNumbers(), session, PacketDirection.UPLINK);
tcpPacket = (TCPPacket) packetInfo.getPacket();
if (packetInfo.getPayloadLen() > 0) {
if (!session.isDataInaccessible()) {
rrInfo = extractHttpRequestResponseInfo(results, session, packetInfo, packetInfo.getDir(), previousPacket, limit);
}
if (rrInfo != null) {
tempRRInfo = rrInfo;
String host = rrInfo.getHostName();
if (host != null) {
URI referrer = rrInfo.getReferrer();
session.setRemoteHostName(host);
session.setDomainName(referrer != null ? referrer.getHost() : host);
}
if (isAnIOSSecureSession(session)) {
break;
}
expectedUploadSeqNo = uploadSequenceNumber + tcpPacket.getPayloadLen();
} else if (tempRRInfo != null) {
int headerDelta = 0;
boolean flag = false;
if (!session.isDataInaccessible() && !tempRRInfo.isHeaderParseComplete()) {
flag = true;
headerDelta = setHeaderOffset(tempRRInfo, packetInfo, tcpPacket);
tempRRInfo.writeHeader(packetInfo, headerDelta);
}
tempRRInfo.setLastDataPacket(packetInfo);
tempRRInfo.setRawSize(tempRRInfo.getRawSize() + packetInfo.getLen() - headerDelta);
if (tcpPacket.getSequenceNumber() == expectedUploadSeqNo) {
expectedUploadSeqNo = tcpPacket.getSequenceNumber() + tcpPacket.getPayloadLen();
tempRRInfo.writePayload(packetInfo, flag, headerDelta);
} else if (tcpPacket.getSequenceNumber() < expectedUploadSeqNo) {
tcpPacket.setRetransmission(true);
} else {
LOGGER.warn("Identified the following Request is corrupt. Session: " + session.getSessionKey() + ". Request Age: " + tempRRInfo.getAge());
tempRRInfo.setCorrupt(true);
tempRRInfo.writePayload(packetInfo, false, 0);
}
} else {
if (session.isDecrypted()) {
continue;
} else if (session.isSsl()) {
break;
}
session.setDataInaccessible(true);
rrInfo = new HttpRequestResponseInfo(session.getRemoteHostName(), packetInfo.getDir());
expectedUploadSeqNo = uploadSequenceNumber + tcpPacket.getPayloadLen();
populateRRInfo(rrInfo, packetInfo, false, true, HttpDirection.REQUEST);
results.add(rrInfo);
tempRRInfo = rrInfo;
}
rrInfo = null;
tempRRInfo.addTCPPacket(uploadSequenceNumber, packetInfo);
}
}
rrInfo = null;
tempRRInfo = null;
if (!(session.isIOSSecureSession() || (session.isSsl() && !session.isDecrypted()))) {
long expectedDownloadSeqNo = 0;
for (long downloadSequenceNumber : session.getDownlinkPacketsSortedBySequenceNumbers().keySet()) {
// Identify correct packet from the whole transmission stream
packetInfo = identifyCorrectTransmissionStream(session.getDownlinkPacketsSortedBySequenceNumbers().get(downloadSequenceNumber), session.getAckNumbers(), session, PacketDirection.DOWNLINK);
tcpPacket = (TCPPacket) packetInfo.getPacket();
if (packetInfo.getPayloadLen() > 0) {
if (!session.isDataInaccessible()) {
rrInfo = extractHttpRequestResponseInfo(results, session, packetInfo, packetInfo.getDir(), previousPacket, limit);
limit = 0;
if (rrInfo != null && !rrInfo.isHeaderParseComplete()) {
previousPacket = packetInfo;
continue;
} else {
previousPacket = null;
}
}
if (rrInfo != null) {
tempRRInfo = rrInfo;
expectedDownloadSeqNo = downloadSequenceNumber + tcpPacket.getPayloadLen();
} else if (tempRRInfo != null) {
boolean flag = false;
int headerDelta = 0;
tempRRInfo.setLastDataPacket(packetInfo);
if (tcpPacket.getSequenceNumber() == expectedDownloadSeqNo) {
expectedDownloadSeqNo = tcpPacket.getSequenceNumber() + tcpPacket.getPayloadLen();
if (tempRRInfo.getContentLength() == 0 || ((tempRRInfo.getPayloadData().size() + packetInfo.getPayloadLen()) <= tempRRInfo.getContentLength())) {
tempRRInfo.writePayload(packetInfo, flag, headerDelta);
tempRRInfo.setRawSize(tempRRInfo.getRawSize() + packetInfo.getLen() - headerDelta);
} else if (tempRRInfo.getContentLength() > 0 && (tempRRInfo.getPayloadData().size() + packetInfo.getPayloadLen()) > tempRRInfo.getContentLength()) {
limit = tempRRInfo.getContentLength() - tempRRInfo.getPayloadData().size();
tempRRInfo.writePayload(packetInfo, limit);
previousPacket = packetInfo;
// TODO: Update RAW SIZE
}
} else if (tcpPacket.getSequenceNumber() < expectedDownloadSeqNo) {
tcpPacket.setRetransmission(true);
} else {
LOGGER.warn("Identified the following Response is corrupt. Session: " + session.getSessionKey() + ". Request Age: " + tempRRInfo.getAge());
tempRRInfo.setCorrupt(true);
tempRRInfo.writePayload(packetInfo, false, 0);
}
} else {
if (session.isDecrypted()) {
continue;
}
rrInfo = new HttpRequestResponseInfo(session.getRemoteHostName(), packetInfo.getDir());
expectedDownloadSeqNo = downloadSequenceNumber + tcpPacket.getPayloadLen();
populateRRInfo(rrInfo, packetInfo, false, true, HttpDirection.RESPONSE);
results.add(rrInfo);
tempRRInfo = rrInfo;
}
rrInfo = null;
tempRRInfo.addTCPPacket(downloadSequenceNumber, packetInfo);
}
}
}
} catch (IOException e) {
LOGGER.error("Error Storing data to TCP Request Response Obect. Session ID: " + session.getSessionKey());
}
if (session.isIOSSecureSession()) {
results = analyzeRequestResponsesForIOSSecureSessions(session);
} else if (session.isSsl() && !session.isDecrypted()) {
results = analyzeRequestResponsesForSecureSessions(session);
}
}
Collections.sort(results);
session.setRequestResponseInfo(results);
populateDataForRequestResponses(session);
if (session.getDomainName() == null) {
session.setDomainName(session.getRemoteIP().getHostName());
}
}
}
Aggregations