Subversion Repositories general

Compare Revisions

Ignore whitespace Rev 1198 → Rev 1199

/TCPproxy/trunk/MainForm.cs
14,7 → 14,7
// - use pool of threads?
// - do not store intermediate info, just row packets and the parsed fragments to display
// - make the text fragment store switchable
// - save/restore window layout
// - set locks and check exceptions during log writing (?)
namespace TCPproxy
{
public class MainForm : System.Windows.Forms.Form
21,8 → 21,13
{
#region constants and settings
 
private const int RECENT_LENGTH = 5;
private const int RECENT_LENGTH = 20;
public const string REGISTRY_KEY = @"Software\Anatoli Klassen\TCPproxy";
public const string REGISTRY_RECENT_SUBKEY = "Recent Listenings";
 
public const byte LOG_TYPE_BIN = 1;
public const string LOG_BIN_HEADER = "TCPproxy 1.0\n";
 
#endregion constants and settings
 
#region private fields
93,6 → 98,8
private MenuItem menuSeparator5;
private MenuItem recentListeningMenu;
private MenuItem recentListeningNoItem;
private SaveFileDialog saveBinLogDialog;
private OpenFileDialog loadBinLogDialog;
private MenuItem aboutMenuItem;
#endregion web forms fields
 
115,10 → 122,12
this.closeConnectionMenuItem = new System.Windows.Forms.MenuItem();
this.viewContextMenu = new System.Windows.Forms.ContextMenu();
this.saveLogDialog = new System.Windows.Forms.SaveFileDialog();
this.mainMenu = new System.Windows.Forms.MainMenu();
this.mainMenu = new System.Windows.Forms.MainMenu(this.components);
this.fileMenu = new System.Windows.Forms.MenuItem();
this.startMenuItem = new System.Windows.Forms.MenuItem();
this.stopMenuItem = new System.Windows.Forms.MenuItem();
this.recentListeningMenu = new System.Windows.Forms.MenuItem();
this.recentListeningNoItem = new System.Windows.Forms.MenuItem();
this.menuSeparator5 = new System.Windows.Forms.MenuItem();
this.loadBinLogMenuItem = new System.Windows.Forms.MenuItem();
this.saveBinLogMenuItem = new System.Windows.Forms.MenuItem();
151,49 → 160,52
this.logBox = new System.Windows.Forms.ListBox();
this.splitter1 = new System.Windows.Forms.Splitter();
this.messageView = new System.Windows.Forms.TreeView();
this.recentListeningMenu = new System.Windows.Forms.MenuItem();
this.recentListeningNoItem = new System.Windows.Forms.MenuItem();
this.saveBinLogDialog = new System.Windows.Forms.SaveFileDialog();
this.loadBinLogDialog = new System.Windows.Forms.OpenFileDialog();
((System.ComponentModel.ISupportInitialize)(this.connectionStatusBar)).BeginInit();
this.panel1.SuspendLayout();
this.panel3.SuspendLayout();
this.panel4.SuspendLayout();
this.SuspendLayout();
//
//
// wordWrapMenuItem
//
//
this.wordWrapMenuItem.Index = 2;
this.wordWrapMenuItem.Text = "Word &Wrap";
this.wordWrapMenuItem.Click += new System.EventHandler(this.wordWrapMenuItem_Click);
//
//
// treeImageList
//
//
this.treeImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("treeImageList.ImageStream")));
this.treeImageList.TransparentColor = System.Drawing.Color.Magenta;
//
this.treeImageList.Images.SetKeyName(0, "");
this.treeImageList.Images.SetKeyName(1, "");
this.treeImageList.Images.SetKeyName(2, "");
//
// messagesContextMenu
//
//
this.messagesContextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.selectAllmenuItem,
this.copyMenuItem,
this.wordWrapMenuItem});
//
//
// selectAllmenuItem
//
//
this.selectAllmenuItem.Index = 0;
this.selectAllmenuItem.Shortcut = System.Windows.Forms.Shortcut.CtrlA;
this.selectAllmenuItem.Text = "Select &All";
this.selectAllmenuItem.Click += new System.EventHandler(this.selectAllMenuItem_Click);
//
//
// copyMenuItem
//
//
this.copyMenuItem.Index = 1;
this.copyMenuItem.Shortcut = System.Windows.Forms.Shortcut.CtrlC;
this.copyMenuItem.Text = "&Copy";
this.copyMenuItem.Click += new System.EventHandler(this.copyMenuItem_Click);
//
//
// statusBar
//
this.statusBar.Location = new System.Drawing.Point(0, 619);
//
this.statusBar.Location = new System.Drawing.Point(0, 359);
this.statusBar.Name = "statusBar";
this.statusBar.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
this.connectionStatusBar});
200,208 → 212,251
this.statusBar.ShowPanels = true;
this.statusBar.Size = new System.Drawing.Size(780, 22);
this.statusBar.TabIndex = 0;
//
//
// connectionStatusBar
//
//
this.connectionStatusBar.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
this.connectionStatusBar.Name = "connectionStatusBar";
this.connectionStatusBar.Width = 764;
//
//
// saveButtonImageList
//
//
this.saveButtonImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("saveButtonImageList.ImageStream")));
this.saveButtonImageList.TransparentColor = System.Drawing.Color.Magenta;
//
this.saveButtonImageList.Images.SetKeyName(0, "");
//
// closeConnectionMenuItem
//
//
this.closeConnectionMenuItem.Index = 0;
this.closeConnectionMenuItem.Text = "&Close connection";
this.closeConnectionMenuItem.Click += new System.EventHandler(this.closeConnectionMenuItem_Click);
//
//
// viewContextMenu
//
//
this.viewContextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.closeConnectionMenuItem});
//
//
// saveLogDialog
//
//
this.saveLogDialog.DefaultExt = "txt";
this.saveLogDialog.Filter = "Text Files|*.txt|All Files|*.*";
this.saveLogDialog.Filter = "Text Files (*.txt)|*.txt|All Files|*.*";
this.saveLogDialog.Title = "Save Log";
//
//
// mainMenu
//
//
this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.fileMenu,
this.viewMenu,
this.helpMenu});
//
this.fileMenu,
this.viewMenu,
this.helpMenu});
//
// fileMenu
//
//
this.fileMenu.Index = 0;
this.fileMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.startMenuItem,
this.stopMenuItem,
this.recentListeningMenu,
this.menuSeparator5,
this.loadBinLogMenuItem,
this.saveBinLogMenuItem,
this.menuSeparator1,
this.saveFullLogMenuItem,
this.saveTcoLogMenuItem,
this.saveHttpLogMenuItem,
this.saveXmlLogMenuItem,
this.menuSeparator2,
this.exitMenuItem});
this.fileMenu.Text = "File";
//
this.startMenuItem,
this.stopMenuItem,
this.recentListeningMenu,
this.menuSeparator5,
this.loadBinLogMenuItem,
this.saveBinLogMenuItem,
this.menuSeparator1,
this.saveFullLogMenuItem,
this.saveTcoLogMenuItem,
this.saveHttpLogMenuItem,
this.saveXmlLogMenuItem,
this.menuSeparator2,
this.exitMenuItem});
this.fileMenu.Text = "&File";
//
// startMenuItem
//
this.startMenuItem.Text = "Start...";
//
this.startMenuItem.Index = 0;
this.startMenuItem.Text = "&Start...";
this.startMenuItem.Click += new System.EventHandler(this.startMenuItem_Click);
//
//
// stopMenuItem
//
//
this.stopMenuItem.Enabled = false;
this.stopMenuItem.Text = "Stop";
this.stopMenuItem.Index = 1;
this.stopMenuItem.Text = "S&top";
this.stopMenuItem.Click += new System.EventHandler(this.stopMenuItem_Click);
//
//
// recentListeningMenu
//
this.recentListeningMenu.Index = 2;
this.recentListeningMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.recentListeningNoItem});
this.recentListeningMenu.Text = "&Recent Listenings";
//
// recentListeningNoItem
//
this.recentListeningNoItem.Enabled = false;
this.recentListeningNoItem.Index = 0;
this.recentListeningNoItem.Text = "(no items)";
//
// menuSeparator5
//
//
this.menuSeparator5.Index = 3;
this.menuSeparator5.Text = "-";
//
//
// loadBinLogMenuItem
//
this.loadBinLogMenuItem.Text = "Load Bin Log...";
//
//
this.loadBinLogMenuItem.Index = 4;
this.loadBinLogMenuItem.Text = "&Load Bin Log...";
this.loadBinLogMenuItem.Click += new System.EventHandler(this.loadBinLogMenuItem_Click);
//
// saveBinLogMenuItem
//
this.saveBinLogMenuItem.Text = "Save Bin Log...";
//
this.saveBinLogMenuItem.Index = 5;
this.saveBinLogMenuItem.Text = "&Save Bin Log...";
this.saveBinLogMenuItem.Click += new System.EventHandler(this.saveBinLogMenuItem_Click);
//
//
// menuSeparator1
//
//
this.menuSeparator1.Index = 6;
this.menuSeparator1.Text = "-";
//
//
// saveFullLogMenuItem
//
this.saveFullLogMenuItem.Text = "Save Full Text Log...";
//
this.saveFullLogMenuItem.Index = 7;
this.saveFullLogMenuItem.Text = "Save F&ull Text Log...";
this.saveFullLogMenuItem.Click += new System.EventHandler(this.saveLogMenuItem_Click);
//
//
// saveTcoLogMenuItem
//
this.saveTcoLogMenuItem.Text = "Save TCP Log...";
//
this.saveTcoLogMenuItem.Index = 8;
this.saveTcoLogMenuItem.Text = "Save T&CP Log...";
this.saveTcoLogMenuItem.Click += new System.EventHandler(this.saveTcpMenuItem_Click);
//
//
// saveHttpLogMenuItem
//
this.saveHttpLogMenuItem.Text = "Save Http Log...";
//
this.saveHttpLogMenuItem.Index = 9;
this.saveHttpLogMenuItem.Text = "Save Htt&p Log...";
this.saveHttpLogMenuItem.Click += new System.EventHandler(this.saveHttpMenuItem_Click);
//
//
// saveXmlLogMenuItem
//
this.saveXmlLogMenuItem.Text = "Save XML Log...";
//
this.saveXmlLogMenuItem.Index = 10;
this.saveXmlLogMenuItem.Text = "Save X&ML Log...";
this.saveXmlLogMenuItem.Click += new System.EventHandler(this.saveXmlMenuItem_Click);
//
//
// menuSeparator2
//
//
this.menuSeparator2.Index = 11;
this.menuSeparator2.Text = "-";
//
//
// exitMenuItem
//
this.exitMenuItem.Text = "Exit";
//
//
this.exitMenuItem.Index = 12;
this.exitMenuItem.Text = "E&xit";
//
// viewMenu
//
//
this.viewMenu.Index = 1;
this.viewMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.clearMainMenuItem,
this.messagesMenu,
this.menuSeparator3,
this.tcpShowByDirectionMenuItem,
this.tcpShowByTimeMenuItem,
this.menuSeparator4,
this.autoExpandMenuItem,
this.wordWrapMainMenuItem});
this.viewMenu.Text = "View";
//
this.clearMainMenuItem,
this.messagesMenu,
this.menuSeparator3,
this.tcpShowByDirectionMenuItem,
this.tcpShowByTimeMenuItem,
this.menuSeparator4,
this.autoExpandMenuItem,
this.wordWrapMainMenuItem});
this.viewMenu.Text = "&View";
//
// clearMainMenuItem
//
this.clearMainMenuItem.Text = "Clear";
//
this.clearMainMenuItem.Index = 0;
this.clearMainMenuItem.Text = "&Clear";
this.clearMainMenuItem.Click += new System.EventHandler(this.clearMenuItem_Click);
//
//
// messagesMenu
//
//
this.messagesMenu.Index = 1;
this.messagesMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.allMessagesMenuItem,
this.infoMessagesMenuItem,
this.importantMessagesMenuItem});
this.messagesMenu.Text = "Messages";
//
this.allMessagesMenuItem,
this.infoMessagesMenuItem,
this.importantMessagesMenuItem});
this.messagesMenu.Text = "&Messages";
//
// allMessagesMenuItem
//
//
this.allMessagesMenuItem.Checked = true;
this.allMessagesMenuItem.Text = "All";
this.allMessagesMenuItem.Index = 0;
this.allMessagesMenuItem.Text = "&All";
this.allMessagesMenuItem.Click += new System.EventHandler(this.messagesMenuItem_Click);
//
//
// infoMessagesMenuItem
//
this.infoMessagesMenuItem.Text = "Info";
//
this.infoMessagesMenuItem.Index = 1;
this.infoMessagesMenuItem.Text = "&Info";
this.infoMessagesMenuItem.Click += new System.EventHandler(this.messagesMenuItem_Click);
//
//
// importantMessagesMenuItem
//
this.importantMessagesMenuItem.Text = "Important";
//
this.importantMessagesMenuItem.Index = 2;
this.importantMessagesMenuItem.Text = "I&mportant";
this.importantMessagesMenuItem.Click += new System.EventHandler(this.messagesMenuItem_Click);
//
//
// menuSeparator3
//
//
this.menuSeparator3.Index = 2;
this.menuSeparator3.Text = "-";
//
//
// tcpShowByDirectionMenuItem
//
//
this.tcpShowByDirectionMenuItem.Checked = true;
this.tcpShowByDirectionMenuItem.Text = "TCP Show by Direction";
this.tcpShowByDirectionMenuItem.Index = 3;
this.tcpShowByDirectionMenuItem.Text = "TCP Show by &Direction";
this.tcpShowByDirectionMenuItem.Click += new System.EventHandler(this.tcpShowByDirectionMenuItem_Click);
//
//
// tcpShowByTimeMenuItem
//
this.tcpShowByTimeMenuItem.Text = "TCP Show by Time";
//
this.tcpShowByTimeMenuItem.Index = 4;
this.tcpShowByTimeMenuItem.Text = "TCP Show by &Time";
this.tcpShowByTimeMenuItem.Click += new System.EventHandler(this.tcpShowByTimeMenuItem_Click);
//
//
// menuSeparator4
//
//
this.menuSeparator4.Index = 5;
this.menuSeparator4.Text = "-";
//
//
// autoExpandMenuItem
//
this.autoExpandMenuItem.Text = "Auto Expand";
//
this.autoExpandMenuItem.Index = 6;
this.autoExpandMenuItem.Text = "Auto E&xpand";
this.autoExpandMenuItem.Click += new System.EventHandler(this.autoExpandMenuItem_Click);
//
//
// wordWrapMainMenuItem
//
this.wordWrapMainMenuItem.Text = "Word Wrap";
//
this.wordWrapMainMenuItem.Index = 7;
this.wordWrapMainMenuItem.Text = "Word &Wrap";
this.wordWrapMainMenuItem.Click += new System.EventHandler(this.wordWrapMenuItem_Click);
//
//
// helpMenu
//
//
this.helpMenu.Index = 2;
this.helpMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.aboutMenuItem});
this.helpMenu.Text = "Help";
//
this.aboutMenuItem});
this.helpMenu.Text = "&Help";
//
// aboutMenuItem
//
this.aboutMenuItem.Text = "About...";
//
this.aboutMenuItem.Index = 0;
this.aboutMenuItem.Text = "&About...";
this.aboutMenuItem.Click += new System.EventHandler(this.aboutMenuItem_Click);
//
//
// panel1
//
//
this.panel1.Controls.Add(this.panel3);
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(0, 24);
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(780, 595);
this.panel1.Size = new System.Drawing.Size(780, 359);
this.panel1.TabIndex = 11;
//
//
// panel3
//
//
this.panel3.Controls.Add(this.panel4);
this.panel3.Controls.Add(this.splitter1);
this.panel3.Controls.Add(this.messageView);
408,11 → 463,11
this.panel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel3.Location = new System.Drawing.Point(0, 0);
this.panel3.Name = "panel3";
this.panel3.Size = new System.Drawing.Size(780, 595);
this.panel3.Size = new System.Drawing.Size(780, 359);
this.panel3.TabIndex = 5;
//
//
// panel4
//
//
this.panel4.Controls.Add(this.messagesBox);
this.panel4.Controls.Add(this.splitter2);
this.panel4.Controls.Add(this.logBox);
419,51 → 474,51
this.panel4.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel4.Location = new System.Drawing.Point(163, 0);
this.panel4.Name = "panel4";
this.panel4.Size = new System.Drawing.Size(617, 595);
this.panel4.Size = new System.Drawing.Size(617, 359);
this.panel4.TabIndex = 13;
//
//
// messagesBox
//
//
this.messagesBox.ContextMenu = this.messagesContextMenu;
this.messagesBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.messagesBox.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.messagesBox.Location = new System.Drawing.Point(0, 0);
this.messagesBox.Name = "messagesBox";
this.messagesBox.Size = new System.Drawing.Size(617, 524);
this.messagesBox.Size = new System.Drawing.Size(617, 288);
this.messagesBox.TabIndex = 7;
this.messagesBox.WordWrap = true;
//
//
// splitter2
//
//
this.splitter2.Dock = System.Windows.Forms.DockStyle.Bottom;
this.splitter2.Location = new System.Drawing.Point(0, 524);
this.splitter2.Location = new System.Drawing.Point(0, 288);
this.splitter2.Name = "splitter2";
this.splitter2.Size = new System.Drawing.Size(617, 3);
this.splitter2.TabIndex = 9;
this.splitter2.TabStop = false;
//
//
// logBox
//
//
this.logBox.Dock = System.Windows.Forms.DockStyle.Bottom;
this.logBox.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.logBox.HorizontalScrollbar = true;
this.logBox.ItemHeight = 16;
this.logBox.Location = new System.Drawing.Point(0, 527);
this.logBox.Location = new System.Drawing.Point(0, 291);
this.logBox.Name = "logBox";
this.logBox.ScrollAlwaysVisible = true;
this.logBox.Size = new System.Drawing.Size(617, 68);
this.logBox.TabIndex = 8;
//
//
// splitter1
//
//
this.splitter1.Location = new System.Drawing.Point(160, 0);
this.splitter1.Name = "splitter1";
this.splitter1.Size = new System.Drawing.Size(3, 595);
this.splitter1.Size = new System.Drawing.Size(3, 359);
this.splitter1.TabIndex = 12;
this.splitter1.TabStop = false;
//
//
// messageView
//
//
this.messageView.ContextMenu = this.viewContextMenu;
this.messageView.Dock = System.Windows.Forms.DockStyle.Left;
this.messageView.HideSelection = false;
472,29 → 527,33
this.messageView.Location = new System.Drawing.Point(0, 0);
this.messageView.Name = "messageView";
this.messageView.SelectedImageIndex = 0;
this.messageView.Size = new System.Drawing.Size(160, 595);
this.messageView.Size = new System.Drawing.Size(160, 359);
this.messageView.TabIndex = 11;
//
// recentListeningMenu
//
this.recentListeningMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.recentListeningNoItem});
this.recentListeningMenu.Text = "Recent Listenings";
//
// recentListeningNoItem
//
this.recentListeningNoItem.Enabled = false;
this.recentListeningNoItem.Text = "(no items)";
//
this.messageView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.messageView_AfterSelect);
this.messageView.BeforeSelect += new System.Windows.Forms.TreeViewCancelEventHandler(this.messageView_BeforeSelect);
//
// saveBinLogDialog
//
this.saveBinLogDialog.DefaultExt = "tcp";
this.saveBinLogDialog.Filter = "TCP Logs (*.bin)|*.bin|All Files|*.*";
this.saveBinLogDialog.Title = "Save Binary Log";
//
// loadBinLogDialog
//
this.loadBinLogDialog.FileName = "openFileDialog1";
this.loadBinLogDialog.Filter = "TCP Logs (*.bin)|*.bin|All Files|*.*";
this.loadBinLogDialog.Title = "Load Binary Log";
//
// MainForm
//
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(780, 641);
this.ClientSize = new System.Drawing.Size(780, 381);
this.Controls.Add(this.panel1);
this.Controls.Add(this.statusBar);
this.Menu = this.mainMenu;
this.MinimumSize = new System.Drawing.Size(400, 200);
this.Name = "MainForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
this.Text = "TCPproxy";
((System.ComponentModel.ISupportInitialize)(this.connectionStatusBar)).EndInit();
this.panel1.ResumeLayout(false);
501,7 → 560,6
this.panel3.ResumeLayout(false);
this.panel4.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
 
}
#endregion
563,104 → 621,6
Application.Run(new MainForm());
}
 
private LogLevel ParseLogLevel(string str)
{
if(str == "Important")
return LogLevel.Important;
else if(str == "Info")
return LogLevel.Info;
else
return LogLevel.Debug;
}
 
private void LoadFromRegistry()
{
Microsoft.Win32.RegistryKey subkey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
@"Software\Anatoli Klassen\TCPproxy");
 
if(subkey == null) return;
 
listenPort = (int)subkey.GetValue("Listen Port", 0);
resendHost = (string)subkey.GetValue("Resend Host", "");
resendPort = (int)subkey.GetValue("Resend Port", 0);
logMessages.Level = ParseLogLevel((string)subkey.GetValue("Messages Level", ""));
autoExpand = (int)subkey.GetValue("Auto Expand", 1) == 1;
messagesBox.WordWrap = (int)subkey.GetValue("Word Wrap", 1) == 1;
 
object tcpShowModeStr = (object)subkey.GetValue("Tcp Show Mode", TcpShowMode.ByDirection);
tcpShowMode = (tcpShowModeStr as string) == "ByDirection"
? TcpShowMode.ByDirection : TcpShowMode.ByTime;
 
// this.Top = (int)subkey.GetValue("Window.Top", this.Top);
// this.Left = (int)subkey.GetValue("Window.Left", this.Left);
// this.Hight = (int)subkey.GetValue("Window.Hight", this.Hight);
// this.Width = (int)subkey.GetValue("Window.Width", this.Width);
}
 
private void LoadRecentItemsFromRegistry()
{
Microsoft.Win32.RegistryKey subkey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
@"Software\Anatoli Klassen\TCPproxy\Recent Listenings");
 
if(subkey == null) return;
 
foreach(string name in subkey.GetValueNames()) {
if(name == "") continue;
AddRecentItem(RecentItem.LoadFromRegistry((string)subkey.GetValue(name, "")));
}
}
 
private void SaveToRegistry()
{
Microsoft.Win32.RegistryKey subkey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(
@"Software\Anatoli Klassen\TCPproxy");
 
subkey.SetValue("Listen Port", listenPort);
subkey.SetValue("Resend Host", resendHost == null ? "" : resendHost);
subkey.SetValue("Resend Port", resendPort);
subkey.SetValue("Messages Level", logMessages.Level);
subkey.SetValue("Tcp Show Mode", tcpShowMode);
subkey.SetValue("Auto Expand", autoExpand ? 1 : 0);
subkey.SetValue("Word Wrap", messagesBox.WordWrap ? 1 : 0);
 
subkey.SetValue("Window.Top", this.Top);
subkey.SetValue("Window.Left", this.Left);
subkey.SetValue("Window.Hight", this.Height);
subkey.SetValue("Window.Width", this.Width);
}
 
private void SaveRecentItemsToRegistry()
{
Microsoft.Win32.RegistryKey subkey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(
@"Software\Anatoli Klassen\TCPproxy\Recent Listenings");
 
// load existing from registry
ArrayList old = new ArrayList();
foreach(string name in subkey.GetValueNames()) {
if(name == "") continue;
old.Add(RecentItem.LoadFromRegistry((string)subkey.GetValue(name, "")));
}
 
// merge - for the case another program instance has changed the list
foreach(RecentItem item in old) {
int existingIdx = recentItems.IndexOf(item);
if(existingIdx >= 0)
((RecentItem)recentItems[existingIdx]).UpdateTimestamp(item);
else
recentItems.Add(item);
}
 
recentItems.Sort();
if(recentItems.Count > 0) // take tail
recentItems = recentItems.GetRange(Math.Max(0, recentItems.Count - RECENT_LENGTH),
Math.Min(recentItems.Count, RECENT_LENGTH));
 
int count = 0;
foreach(RecentItem item in recentItems) {
subkey.SetValue(string.Format("{0:0000}", count++), item.SaveToRegistry());
}
}
 
private void startMenuItem_Click(object sender, System.EventArgs e)
{
IPAddress resendIp;
671,61 → 631,14
StartListening(listenPort, resendIp, resendPort);
}
 
private void StartListening(int listenPort, IPAddress resendIp, int resendPort)
{
// listen to the port
try
{
Start(listenPort, resendIp, resendPort);
}
catch(Exception ex)
{
MessageBox.Show("Cannot start listening: " + ex.Message, "TCPproxy",
MessageBoxButtons.OK, MessageBoxIcon.Error);
Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
return;
}
 
AddRecentItem(listenPort, resendHost, resendPort);
 
startMenuItem.Enabled = false;
stopMenuItem.Enabled = true;
 
foreach(MenuItem subitem in recentListeningMenu.MenuItems) {
subitem.Enabled = false;
}
 
this.Text = string.Format("{0}: {1} to {2}:{3}",
defaultCaption, listenPort, resendHost, resendPort);
}
 
private void stopMenuItem_Click(object sender, System.EventArgs e)
{
if(tcpListener != null) tcpListener.StopListening();
 
startMenuItem.Enabled = true;
stopMenuItem.Enabled = false;
 
if(recentItems.Count > 0) {
foreach(MenuItem subitem in recentListeningMenu.MenuItems) {
subitem.Enabled = true;
}
}
 
this.Text = defaultCaption;
StopListening();
}
 
private void clearMenuItem_Click(object sender, System.EventArgs e)
{
// close all connetions
foreach(object tcp in treeNodes.Keys)
if(tcp is TcpConnection)
((TcpConnection)tcp).Cancel();
 
treeNodes.Clear();
messageView.Nodes.Clear();
messagesBox.Clear();
logMessages.Clear();
ClearAll();
}
 
private void selectAllMenuItem_Click(object sender, System.EventArgs e)
852,6 → 765,18
}
}
 
private void saveBinLogMenuItem_Click(object sender, EventArgs e)
{
if(saveBinLogDialog.ShowDialog() == DialogResult.OK)
SaveBinLog(saveBinLogDialog.FileName);
}
 
private void loadBinLogMenuItem_Click(object sender, EventArgs e)
{
if(loadBinLogDialog.ShowDialog() == DialogResult.OK)
LoadBinLog(loadBinLogDialog.FileName);
}
 
private void messagesMenuItem_Click(object sender, EventArgs e)
{
if(sender == importantMessagesMenuItem)
864,11 → 789,6
UpdateMessagesMenuItems();
}
 
private void saveBinLogMenuItem_Click(object sender, EventArgs e)
{
 
}
 
private void recentMenuItem_Click(object sender, EventArgs e)
{
int n = recentItems.Count-1;
899,6 → 819,123
StartListening(listenPort, resendIp, resendPort);
}
 
#endregion windows forms methods
 
#region core methods
 
private LogLevel ParseLogLevel(string str)
{
if(str == "Important")
return LogLevel.Important;
else if(str == "Info")
return LogLevel.Info;
else
return LogLevel.Debug;
}
 
private void LoadFromRegistry()
{
Microsoft.Win32.RegistryKey subkey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
REGISTRY_KEY);
 
if(subkey == null) return;
 
listenPort = (int)subkey.GetValue("Listen Port", 0);
resendHost = (string)subkey.GetValue("Resend Host", "");
resendPort = (int)subkey.GetValue("Resend Port", 0);
logMessages.Level = ParseLogLevel((string)subkey.GetValue("Messages Level", ""));
autoExpand = (int)subkey.GetValue("Auto Expand", 1) == 1;
messagesBox.WordWrap = (int)subkey.GetValue("Word Wrap", 1) == 1;
 
object tcpShowModeStr = (object)subkey.GetValue("Tcp Show Mode", TcpShowMode.ByDirection);
tcpShowMode = (tcpShowModeStr as string) == "ByDirection"
? TcpShowMode.ByDirection : TcpShowMode.ByTime;
 
int winTop = (int)subkey.GetValue("Window.Top", -1);
int winLeft = (int)subkey.GetValue("Window.Left", -1);
 
if(winTop == -1 || winLeft == -1) {
this.StartPosition = FormStartPosition.WindowsDefaultBounds;
}
else {
this.Top = winTop;
this.Left = winLeft;
this.ClientSize = new Size(
(int)subkey.GetValue("Window.Width", this.ClientSize.Width),
(int)subkey.GetValue("Window.Hight", this.ClientSize.Height));
this.messageView.Width
= (int)subkey.GetValue("Splitter.Left", this.messageView.Width);
this.logBox.Height
= (int)subkey.GetValue("Splitter.Bottom", this.logBox.Height);
}
}
 
private void LoadRecentItemsFromRegistry()
{
Microsoft.Win32.RegistryKey subkey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
REGISTRY_KEY + @"\" + REGISTRY_RECENT_SUBKEY);
 
if(subkey == null) return;
 
foreach(string name in subkey.GetValueNames()) {
if(name == "") continue;
AddRecentItem(RecentItem.LoadFromRegistry((string)subkey.GetValue(name, "")));
}
}
 
private void SaveToRegistry()
{
Microsoft.Win32.RegistryKey subkey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(
REGISTRY_KEY);
 
subkey.SetValue("Listen Port", listenPort);
subkey.SetValue("Resend Host", resendHost == null ? "" : resendHost);
subkey.SetValue("Resend Port", resendPort);
subkey.SetValue("Messages Level", logMessages.Level);
subkey.SetValue("Tcp Show Mode", tcpShowMode);
subkey.SetValue("Auto Expand", autoExpand ? 1 : 0);
subkey.SetValue("Word Wrap", messagesBox.WordWrap ? 1 : 0);
 
subkey.SetValue("Window.Top", this.Top);
subkey.SetValue("Window.Left", this.Left);
subkey.SetValue("Window.Hight", this.ClientSize.Height);
subkey.SetValue("Window.Width", this.ClientSize.Width);
subkey.SetValue("Splitter.Left", this.messageView.Width);
subkey.SetValue("Splitter.Bottom", this.logBox.Height);
}
 
private void SaveRecentItemsToRegistry()
{
Microsoft.Win32.RegistryKey subkey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(
REGISTRY_KEY + @"\" + REGISTRY_RECENT_SUBKEY);
 
// load existing from registry
ArrayList old = new ArrayList();
foreach(string name in subkey.GetValueNames()) {
if(name == "") continue;
old.Add(RecentItem.LoadFromRegistry((string)subkey.GetValue(name, "")));
}
 
// merge - for the case another program instance has changed the list
foreach(RecentItem item in old) {
int existingIdx = recentItems.IndexOf(item);
if(existingIdx >= 0)
((RecentItem)recentItems[existingIdx]).UpdateTimestamp(item);
else
recentItems.Add(item);
}
 
recentItems.Sort();
if(recentItems.Count > 0) // take tail
recentItems = recentItems.GetRange(Math.Max(0, recentItems.Count - RECENT_LENGTH),
Math.Min(recentItems.Count, RECENT_LENGTH));
 
int count = 0;
foreach(RecentItem item in recentItems) {
subkey.SetValue(string.Format("{0:0000}", count++), item.SaveToRegistry());
}
}
 
private void UpdateMessagesMenuItems()
{
switch(logMessages.Level) {
947,7 → 984,7
 
MenuItem menuItem = new MenuItem();
this.recentListeningMenu.MenuItems.Add(0, menuItem);
menuItem.Text = string.Format("{0} to {1}:{2}",
menuItem.Text = string.Format("&1 {0} to {1}:{2}",
recentItem.ListenPort, recentItem.ResendHost, recentItem.ResendPort);
menuItem.Click += new System.EventHandler(recentMenuItem_Click);
 
956,11 → 993,37
recentItems.RemoveAt(0);
this.recentListeningMenu.MenuItems.RemoveAt(RECENT_LENGTH-1);
}
 
// update hot keys of old items
int count = 0;
foreach(MenuItem item in this.recentListeningMenu.MenuItems) {
if(count == 0) {
}
else if(count < 10)
item.Text = string.Format("&{3} {0} to {1}:{2}", recentItem.ListenPort,
recentItem.ResendHost, recentItem.ResendPort, count + 1);
else
item.Text = string.Format("{0} to {1}:{2}", recentItem.ListenPort,
recentItem.ResendHost, recentItem.ResendPort);
count++;
}
}
 
#endregion windows forms methods
private void ClearAll()
{
// close all connetions
foreach(object tcp in treeNodes.Keys)
if(tcp is TcpConnection)
((TcpConnection)tcp).Cancel();
 
#region core methods
// FIXME wait for all log messages from network part
 
treeNodes.Clear();
messageView.Nodes.Clear();
messagesBox.Clear();
logMessages.Clear();
}
 
private void Start(int listenPort, IPAddress resendHost, int resendPort)
{
if(tcpListener != null) tcpListener.StopListening();
971,6 → 1034,50
tcpListener.StartListening();
}
 
private void StartListening(int listenPort, IPAddress resendIp, int resendPort)
{
// listen to the port
try
{
Start(listenPort, resendIp, resendPort);
}
catch(Exception ex)
{
MessageBox.Show("Cannot start listening: " + ex.Message, "TCPproxy",
MessageBoxButtons.OK, MessageBoxIcon.Error);
Console.WriteLine(ex.Message + " (" + ex.GetType().Name + ")\n" + ex.StackTrace);
return;
}
 
AddRecentItem(listenPort, resendHost, resendPort);
 
startMenuItem.Enabled = false;
stopMenuItem.Enabled = true;
 
foreach(MenuItem subitem in recentListeningMenu.MenuItems) {
subitem.Enabled = false;
}
 
this.Text = string.Format("{0}: {1} to {2}:{3}",
defaultCaption, listenPort, resendHost, resendPort);
}
 
private void StopListening()
{
if(tcpListener != null) tcpListener.StopListening();
 
startMenuItem.Enabled = true;
stopMenuItem.Enabled = false;
 
if(recentItems.Count > 0) {
foreach(MenuItem subitem in recentListeningMenu.MenuItems) {
subitem.Enabled = true;
}
}
 
this.Text = defaultCaption;
}
 
private void CloseTcpConnection(TcpConnection tcp)
{
if(tcp == null) return;
1038,6 → 1145,56
writer.Close();
}
 
private void SaveBinLog(string fileName)
{
FileStream file = new FileStream(fileName, FileMode.Create);
BinaryWriter writer = new BinaryWriter(file);
 
// header
writer.Write(Encoding.ASCII.GetBytes(LOG_BIN_HEADER));
writer.Write(LOG_TYPE_BIN);
 
// for each tcp connection
foreach(TreeNode tcpNode in messageView.Nodes)
((TcpNodeData)tcpNode.Tag).Tcp.WriteBinLog(writer);
 
// end of stream
writer.Write((byte)BinLogTypes.None);
 
writer.Close();
file.Close();
}
 
private void LoadBinLog(string fileName)
{
StopListening();
ClearAll();
 
FileStream file = new FileStream(fileName, FileMode.Open);
BinaryReader reader = new BinaryReader(file);
 
// header
byte[] bufExpect = Encoding.ASCII.GetBytes(LOG_BIN_HEADER);
if(file.Length < bufExpect.Length + sizeof(byte))
throw new Exception("The file is too short");
 
byte[] bufRead = reader.ReadBytes(bufExpect.Length);
for(int i = 0; i < bufRead.Length; i++)
if(bufRead[i] != bufExpect[i])
throw new Exception("Wrong header of the file");
 
if(reader.ReadByte() != LOG_TYPE_BIN)
throw new Exception("Unknown log type");
 
tcpListener = new TcpListener(0, null, 0);
tcpListener.Log += new TcpLogEventHandler(TcpConnectionLog);
tcpListener.NewTcp += new TcpConnectionEventHandler(AddTcpConnetion);
tcpListener.ReadBinLog(reader); // it will send us usual event
 
reader.Close();
file.Close();
}
 
#endregion core methods
 
#region network events handlers
1159,8 → 1316,9
 
data.Tcp = tcp;
treeNode.Tag = data;
treeNode.ImageIndex = 1;
treeNode.SelectedImageIndex = 1;
treeNode.ImageIndex = (tcp.LocalState == SocketState.Closed
&& tcp.RemoteState == SocketState.Closed) ? 2 : 1;
treeNode.SelectedImageIndex = treeNode.ImageIndex;
treeNodes[tcp] = data;
 
messageView.Nodes.Add(treeNode);
1177,7 → 1335,7
if(tcp.LocalState == SocketState.Closed && tcp.RemoteState == SocketState.Closed)
{
data.Node.ImageIndex = 2;
data.Node.SelectedImageIndex = 2;
data.Node.SelectedImageIndex = data.Node.ImageIndex;
}
 
if(messageView.SelectedNode == null || data != messageView.SelectedNode.Tag)
/TCPproxy/trunk/Network.cs
1,5 → 1,6
using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
12,6 → 13,12
// FIXME option to not store parsed data, just raw packets and reparse on demand
namespace TCPproxy
{
public enum BinLogTypes
{
None = 1,
TcpConnection
}
 
public enum LogLevel
{
Critical,
34,6 → 41,7
 
public enum TcpMessageDirection
{
None,
Local,
Remote
}
251,6 → 259,15
TcpLogEventArgs e = new TcpLogEventArgs(level, null, ex);
OnLog(e);
}
 
public void ReadBinLog(BinaryReader reader)
{
// tcp connections
TcpConnection tcp;
while((tcp = TcpConnection.ReadBinLog(reader)) != null) {
OnNewTcp(new TcpConnectionEventArgs(tcp));
}
}
}
 
public class TcpConnection
350,7 → 367,8
 
public void Cancel()
{
worker.Cancel();
if(worker != null)
worker.Cancel();
}
 
protected TcpMessage Append(TcpMessageDirection direction, byte[] newBytes)
388,13 → 406,11
}
}
 
 
public override string ToString() // FIXME delete the method
{
return id + " " + startTimestamp.ToString("HH:mm:ss.ffff");
}
 
 
protected void SetLocalPoint(IPEndPoint localPoint)
{
this.localPoint = localPoint;
575,6 → 591,113
OnLog(e);
}
 
private void WriteEndPoint(BinaryWriter writer, IPEndPoint endPoint)
{
// end point as (family as int, ip length, ip as bytes, port)
byte[] ipBuf = endPoint.Address.GetAddressBytes();
writer.Write((UInt32)endPoint.AddressFamily);
writer.Write((UInt32)ipBuf.Length);
writer.Write(ipBuf);
writer.Write((UInt32)endPoint.Port);
}
 
public void WriteBinLog(BinaryWriter writer)
{
// header
writer.Write((byte)BinLogTypes.TcpConnection);
 
// id as (length, UTF-8)
byte[] idBuf = Encoding.UTF8.GetBytes(id);
writer.Write((UInt32)idBuf.Length);
writer.Write(idBuf);
 
// timestamps as ticks
writer.Write((UInt64)startTimestamp.Ticks);
writer.Write((UInt64)localEndTimestamp.Ticks);
writer.Write((UInt64)remoteEndTimestamp.Ticks);
 
// end points as (family as int, ip length, ip as bytes, port)
WriteEndPoint(writer, localPoint);
WriteEndPoint(writer, remotePoint);
 
// states as byte
writer.Write((byte)localState);
writer.Write((byte)remoteState);
 
// each tcp message as (direction as byte, timestamp in ticks, length, content)
foreach(TcpMessage message in messages) {
writer.Write((byte)message.Direction);
writer.Write((UInt64)message.Timestamp.Ticks);
writer.Write((UInt32)message.Length);
writer.Write(message.Bytes, 0, message.Length);
}
 
// end of stream marker
writer.Write((byte)TcpMessageDirection.None);
}
 
private static IPEndPoint ReadEndPoint(BinaryReader reader)
{
// end point as (family as int, ip length, ip as bytes, port)
AddressFamily fam = (AddressFamily)reader.ReadInt32();
int addressLength = reader.ReadInt32();
byte[] addressBytes = reader.ReadBytes(addressLength);
int port = reader.ReadInt32();
IPAddress address = new IPAddress(addressBytes);
 
return new IPEndPoint(address, port);
}
 
internal static TcpConnection ReadBinLog(BinaryReader reader)
{
// header
BinLogTypes recordType = (BinLogTypes)reader.ReadByte();
 
if(recordType == BinLogTypes.None)
return null;
else if(recordType == BinLogTypes.TcpConnection) {
}
else
throw new Exception("Wrong data type");
 
// id as (length, UTF-8)
int idLength = (int)reader.ReadUInt32();
string id = Encoding.UTF8.GetString(reader.ReadBytes(idLength));
 
TcpConnection tcp = new TcpConnection(id);
 
// timestamps as ticks
tcp.startTimestamp = new DateTime((long)reader.ReadUInt64());
tcp.localEndTimestamp = new DateTime((long)reader.ReadUInt64());
tcp.remoteEndTimestamp = new DateTime((long)reader.ReadUInt64());
 
// end points as (family as int, ip length, ip as bytes, port)
tcp.localPoint = ReadEndPoint(reader);
tcp.remotePoint = ReadEndPoint(reader);
 
// states as byte - read but ignore
reader.ReadByte();
reader.ReadByte();
 
// each tcp message as (direction as byte, timestamp in ticks, length, content)
tcp.localState = SocketState.Closed;
tcp.remoteState = SocketState.Closed;
for(;;) {
TcpMessageDirection direction = (TcpMessageDirection)reader.ReadByte();
if(direction == TcpMessageDirection.None) break; // end of stream marker
 
DateTime timestamp = new DateTime((long)reader.ReadUInt64());
int bufLength = (int)reader.ReadUInt32();
byte[] buf = reader.ReadBytes(bufLength);
 
TcpMessage msg = tcp.Append(direction, buf);
msg.SetTimestamp(timestamp);
}
tcp.OnUpdate(new TcpEventArgs());
 
return tcp;
}
 
protected class SocketWorker
{
private enum SendCommandType
1208,6 → 1331,9
{
newMessageEvent.Reset();
moved = messagesEnum.MoveNext();
 
if(!moved && messages.LocalState == SocketState.Closed && messages.RemoteState == SocketState.Closed)
return false;
}
 
if(moved) break;
1293,20 → 1419,19
}
}
 
private TcpConnection messages;
private AutoResetEvent requestEvent = new AutoResetEvent(false); // new request found
private AutoResetEvent nextMessageEvent = new AutoResetEvent(false); // request goes to next TCP message
private LinkedList https = new LinkedList();
private ParsePosition requestPos;
private ParsePosition responsePos;
private AutoResetEvent newMessageEvent = new AutoResetEvent(false); // new TCP message available
private Thread runThread;
private TcpConnection messages;
private AutoResetEvent requestEvent = new AutoResetEvent(false); // new request found
private AutoResetEvent nextMessageEvent = new AutoResetEvent(false); // request goes to next TCP message
private LinkedList https = new LinkedList();
private ParsePosition requestPos;
private ParsePosition responsePos;
private Thread runThread;
 
public static HttpParser Parse(TcpConnection messages)
{
HttpParser parser = new HttpParser(messages);
parser.runThread = new Thread(new ThreadStart(parser.Run));
parser.RunThread.Name = "HttpParser.Run";
parser.runThread.Name = "HttpParser.Run";
parser.runThread.Start();
 
return parser;
1325,7 → 1450,9
 
private HttpParser(TcpConnection messages)
{
this.messages = messages;
this.messages = messages;
this.requestPos = new ParsePosition(messages, nextMessageEvent);
this.responsePos = new ParsePosition(messages, null);
InitTables();
}
 
1338,9 → 1465,6
 
try
{
requestPos = new ParsePosition(messages, nextMessageEvent);
responsePos = new ParsePosition(messages, null);
 
responseThread = new Thread(new ThreadStart(MatchResponses));
responseThread.Name = "HttpParser.MatchResponses";
responseThread.Start();
2240,7 → 2364,7
 
public class TcpMessage
{
private TcpMessageDirection direction;
private TcpMessageDirection direction = TcpMessageDirection.None;
private byte[] bytes;
private int length = 0;
private DateTime timestamp;
2274,6 → 2398,11
get { return timestamp; }
}
 
internal void SetTimestamp(DateTime timestamp)
{
this.timestamp = timestamp;
}
 
internal TcpMessage()
{
this.timestamp = DateTime.Now;
/TCPproxy/trunk/MainForm.resx
216,4 → 216,10
<metadata name="mainMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 54</value>
</metadata>
<metadata name="saveBinLogDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>120, 54</value>
</metadata>
<metadata name="loadBinLogDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>259, 52</value>
</metadata>
</root>