Example #1
0
        /// <summary>
        /// Completes the initial connection to the proxy server
        /// </summary>
        /// <remarks>This method is used to complete the proxy server transaction for both
        /// Stage 1 sending and Stage 2 receiver-redirect proxy scenarios</remarks>
        private void InitProxyConnectFinished(IAsyncResult res)
        {
            RendezvousData    rd  = res.AsyncState as RendezvousData;
            DirectConnectInfo fti = rd.DirectConnection;

            try
            {
                fti.Transfer.EndConnect(res);

                ProxyInitializeSend(rd);
                RendezvousProxyPacket rpp = ReadProxyPacket(rd);
                if (rpp.Command == RendezvousProxyCommand.Acknowledge)
                {
                    rd.Port = Marshal.ByteArrayToUshort(rpp.Data, 0);
                    byte[] ipaddr = new byte[4];
                    Marshal.CopyArray(rpp.Data, ipaddr, 2);
                    rd.ProxyIP = (new IPAddress(ipaddr)).ToString();

                    // Send the "send file" request on SNAC(04,06):02
                    // SNAC04.SendDirectConnectionRequest(_parent, rd);

                    // Wait for the proxy to send its 12 byte READY sequence
                    rd.DirectConnection.Transfer.BeginReceive(new byte[12], 0, 12,
                                                              SocketFlags.None, new AsyncCallback(ProxyReceivedReady), rd);
                }
                else
                {
                    int    index = 0;
                    ushort error = Marshal.ByteArrayToUshort(rpp.Data, ref index);
                    if (error == 0x0004)
                    {
                        throw new Exception("Recipient not logged in");
                    }
                    else if (error == 0x000D)
                    {
                        throw new Exception("Client sent bad request");
                    }
                    throw new Exception("AOL proxy sent unknown error");
                }
            }
            catch (Exception ex)
            {
                fti.CancelTransfer(ex.Message);
            }
        }
Example #2
0
        /// <summary>
        /// Constructs a new RendezvousData object for a file transfer
        /// </summary>
        private RendezvousData CreateSendFileData(string recipient, string filename)
        {
            // Set up a direct connection information structure
            RendezvousData rd = new RendezvousData();

            rd.UserInfo            = new UserInfo();
            rd.UserInfo.ScreenName = recipient;
            rd.ParentSession       = _parent;
            rd.Capability          = Capabilities.SendFiles;
            rd.Type = 0x0000;

            DirectConnectInfo fti = new DirectConnectInfo(rd, DirectConnectType.FileTransfer);

            // Put the basename of the file into the structure
            int slashindex = filename.LastIndexOf("\\");

            fti.Header.Name   = filename.Substring(slashindex + 1, filename.Length - (slashindex + 1));
            fti.LocalFileName = filename;

            // Get the size of the file to put in the structure and checksum it
            fti.Header.Size     = (uint)(new FileInfo(filename)).Length;
            fti.Header.Checksum = Checksum(_parent, filename);

            // Couldn't locate the passed-in file
            if (fti.Header.Checksum == 0xFFFFFFFF)
            {
                return(null);
            }

            // Set the totals. Eventually OscarLib may support > 1 files at a time
            fti.TotalFiles = 1;
            fti.TotalParts = 1;
            fti.FilesLeft  = 1;
            fti.TotalSize  = fti.Header.Size;

            rd.DirectConnection = fti;
            return(rd);
        }
Example #3
0
        /// <summary>
        /// Constructs a new RendezvousData object for a file transfer
        /// </summary>
        private RendezvousData CreateSendFileData(string recipient, string filename)
        {
            // Set up a direct connection information structure
              RendezvousData rd = new RendezvousData();
              rd.UserInfo = new UserInfo();
              rd.UserInfo.ScreenName = recipient;
              rd.ParentSession = _parent;
              rd.Capability = Capabilities.SendFiles;
              rd.Type = 0x0000;

              DirectConnectInfo fti = new DirectConnectInfo(rd, DirectConnectType.FileTransfer);

              // Put the basename of the file into the structure
              int slashindex = filename.LastIndexOf("\\");
              fti.Header.Name = filename.Substring(slashindex + 1, filename.Length - (slashindex + 1));
              fti.LocalFileName = filename;

              // Get the size of the file to put in the structure and checksum it
              fti.Header.Size = (uint)(new FileInfo(filename)).Length;
              fti.Header.Checksum = Checksum(_parent, filename);

              // Couldn't locate the passed-in file
              if (fti.Header.Checksum == 0xFFFFFFFF)
              {
            return null;
              }

              // Set the totals. Eventually OscarLib may support > 1 files at a time
              fti.TotalFiles = 1;
              fti.TotalParts = 1;
              fti.FilesLeft = 1;
              fti.TotalSize = fti.Header.Size;

              rd.DirectConnection = fti;
              return rd;
        }
Example #4
0
        /// <summary>
        /// The callback function for socket reads during a file transfer
        /// </summary>
        /// <param name="res">An <see cref="IAsyncResult"/> object</param>
        private void SendFileTransferReceive(IAsyncResult res)
        {
            int               bytesread = 0;
            RendezvousData    rd        = (RendezvousData)res.AsyncState;
            DirectConnectInfo fti       = rd.DirectConnection;

            // End the async receive operation
            try
            {
                bytesread = fti.Transfer.EndReceive(res);
                if (bytesread == 0)
                {
                    throw new Exception("Remote client cancelled transfer");
                }
            }
            catch (Exception ex)
            {
                rd.DirectConnection.CancelTransfer(ex.Message);
                return;
            }

            // Write the received data out to the file
            try
            {
                fti.DataStream.Write(fti.DataChunk, 0, bytesread);
                fti.StreamPosition += (uint)bytesread;
            }
            catch (Exception ex)
            {
                rd.DirectConnection.CancelTransfer(ex.Message);
                return;
            }

            // Checksum the received chunk
            fti.Header.ReceivedChecksum = ChecksumChunk(fti.DataChunk, (uint)bytesread, fti.Header.ReceivedChecksum);

            // Signal progress to the parent session
            rd.ParentSession.OnFileTransferProgress(
                RendezvousManager.GetKeyFromCookie(rd.Cookie),
                rd.DirectConnection.StreamPosition,
                rd.DirectConnection.Header.Size);

            // Check to see if the transfer has finished
            if (fti.StreamPosition >= fti.Header.Size)
            {
                fti.DataChunk = null;
                fti.DataStream.Close();

                // Send out the acknowledgement, compare the checksums, and finish up
                SendFileReceiverDone(rd);

                if (fti.Header.ReceivedChecksum != fti.Header.Checksum)
                {
                    rd.DirectConnection.CancelTransfer("Received data does not match expected checksum");
                    return;
                }

                rd.DirectConnection.CompleteTransfer();
            }
            else
            {
                // Keep receiving asynchronously
                fti.Transfer.BeginReceive(fti.DataChunk, 0, fti.DataChunk.Length,
                                          SocketFlags.None, new AsyncCallback(SendFileTransferReceive), rd);
            }
        }
Example #5
0
        /// <summary>
        /// Receives the PROMPT message and responds with an ACK message, then prepares the transfer socket to receive data
        /// </summary>
        /// <param name="rd">The <see cref="RendezvousData"/> object receiving a file</param>
        private void BeginReceiveFile(RendezvousData rd)
        {
            byte[] filetransferheader = null;
            int    index = 0;

            // Read in 256 bytes, PROMPT type and blank cookie

            filetransferheader = new byte[256];
            try
            {
                while (index < filetransferheader.Length)
                {
                    index += rd.DirectConnection.Transfer.Receive(
                        filetransferheader,
                        index,
                        filetransferheader.Length - index,
                        SocketFlags.None);
                }
            }
            catch (Exception ex)
            {
                string message = "Error negotiating file transfer:" + Environ.NewLine + ex.Message;
                throw new Exception(message);
            }

            index = 8;
            DirectConnectInfo dci = rd.DirectConnection;

            //Marshal.ByteArrayToFTI(filetransferheader, ref index, ref dci);
            rd.DirectConnection = dci; // Just to be sure

            // Respond with the same header, but with the ACK type and the ICBM cookie set
            index = 6;
            Marshal.InsertUshort(filetransferheader, 0x0202, ref index);
            Marshal.CopyArray(rd.Cookie, filetransferheader, 0, ref index);

            index = 0;
            try
            {
                while (index < filetransferheader.Length)
                {
                    index += rd.DirectConnection.Transfer.Send(
                        filetransferheader,
                        index,
                        filetransferheader.Length - index,
                        SocketFlags.None);
                }
            }
            catch (Exception ex)
            {
                string message = "Error negotiating file transfer:" + Environ.NewLine + ex.Message;
                throw new Exception(message);
            }

            // Open the file for writing
            try
            {
                rd.DirectConnection.DataChunk      = new byte[8192];
                rd.DirectConnection.DataStream     = (new StreamWriter(rd.DirectConnection.LocalFileName, false)).BaseStream;
                rd.DirectConnection.StreamPosition = 0;
            }
            catch (Exception)
            {
                throw new Exception("Can't open target file for writing");
            }

            // Signal the parent session that the file transfer has started
            rd.ParentSession.OnFileTransferProgress(RendezvousManager.GetKeyFromCookie(rd.Cookie),
                                                    0, rd.DirectConnection.Header.Size);

            // Start receiving data
            rd.DirectConnection.Transfer.BeginReceive(rd.DirectConnection.DataChunk, 0,
                                                      rd.DirectConnection.DataChunk.Length,
                                                      SocketFlags.None, new AsyncCallback(SendFileTransferReceive), rd);
        }