/// <summary> /// WaitCallback method for performing a byte[] scan on an independent thread using System.Treading.QueueUserWorkItem. /// </summary> /// <exception cref="ArgumentException">Throws argument "o" is not an instance of StreamScanArgs.</exception> /// <param name="o">Instance of StreamScanArgs.</param> protected virtual void DoStreamScan(object o) { if (!(o is StreamScanArgs)) { throw new ArgumentException(ResourceManagers.Strings.GetString(STR_DO_BYTE_SCAN_ARG_EX)); } StreamScanArgs scanArgs = (StreamScanArgs)o; StreamScan(scanArgs); }
/// <summary> /// Scan a byte[] bag. /// </summary> /// <param name="id">Unique identifier for the buffer (eg. filename, url or database key, etc.)</param> /// <param name="stream">Stream to scan</param> public override void Scan(string id, Stream stream) { StreamScanArgs args = new StreamScanArgs(id, stream); switch (_threadModel) { case VirusScanAgent.ThreadingModel.AsynchronousThreadPool: ThreadPool.QueueUserWorkItem(new WaitCallback(this.DoStreamScan), args); break; case VirusScanAgent.ThreadingModel.SynchronousSingleThread: StreamScan(args); break; default: throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, ResourceManagers.Strings.GetString(STR_SCAN_NOT_SUPPORTED_EX_THREADING), _threadModel)); } }
/// <summary> /// Method scans a byte[] by passing it to clamd over a dynamically allocated port. The real magic happens here. /// The ItemScanCompleted event is raised whenever this method completes. If a virus is found, this method raises /// the VirusFound event. /// </summary> /// <param name="args">StreamScanArgs instance.</param> protected virtual void StreamScan(StreamScanArgs args) { string outstr = null; try { using (TcpClient tcpclient = new TcpClient(this.ClamdHost, this.ClamdPort)) using (NetworkStream netStream = tcpclient.GetStream()) using (StreamWriter outputStream = new StreamWriter(netStream)) using (StreamReader inputStream = new StreamReader(netStream)) { outputStream.WriteLine(SCAN_VERB); outputStream.Flush(); string portstr = inputStream.ReadLine(); string[] daemonargs = portstr.Split(' '); SendStream(args.Stream, int.Parse(daemonargs[daemonargs.Length - 1], CultureInfo.InvariantCulture)); outstr = inputStream.ReadLine(); outputStream.Close(); inputStream.Close(); netStream.Close(); tcpclient.Close(); } if (outstr != null && outstr.IndexOf(FOUND) > -1) { this.OnVirusFound(new ScanCompletedEventArgs(args.Id, outstr)); } this.OnItemScanCompleted(new ScanCompletedEventArgs(args.Id, outstr)); //reset retry counter _netRetryCount = 0; } catch (Exception ex) { if (ex is SocketException || ex is IOException) { if (_netRetryCount < MAX_NET_RETRY) { //increment retry count and try again _netRetryCount++; StreamScan(args); } else { //reset retry count log error and return _netRetryCount = 0; if (_logger.IsDebugEnabled) { _logger.Error(ex); } else { _logger.Error(ex.Message); } } } else { throw; } } }
/// <summary> /// Scan a byte[] bag. /// </summary> /// <param name="id">Unique identifier for the buffer (eg. filename, url or database key, etc.)</param> /// <param name="stream">Stream to scan</param> public override void Scan(string id, Stream stream) { StreamScanArgs args = new StreamScanArgs(id,stream); switch(_threadModel) { case VirusScanAgent.ThreadingModel.AsynchronousThreadPool : ThreadPool.QueueUserWorkItem( new WaitCallback( this.DoStreamScan ), args ); break; case VirusScanAgent.ThreadingModel.SynchronousSingleThread : StreamScan(args); break; default : throw new NotSupportedException( string.Format(CultureInfo.CurrentCulture, ResourceManagers.Strings.GetString(STR_SCAN_NOT_SUPPORTED_EX_THREADING), _threadModel) ); } }
/// <summary> /// Method scans a byte[] by passing it to clamd over a dynamically allocated port. The real magic happens here. /// The ItemScanCompleted event is raised whenever this method completes. If a virus is found, this method raises /// the VirusFound event. /// </summary> /// <param name="args">StreamScanArgs instance.</param> protected virtual void StreamScan(StreamScanArgs args) { string outstr = null; try { using ( TcpClient tcpclient = new TcpClient( this.ClamdHost, this.ClamdPort ) ) using (NetworkStream netStream = tcpclient.GetStream() ) using (StreamWriter outputStream = new StreamWriter(netStream) ) using (StreamReader inputStream = new StreamReader(netStream) ) { outputStream.WriteLine( SCAN_VERB ); outputStream.Flush(); string portstr = inputStream.ReadLine(); string[] daemonargs = portstr.Split(' '); SendStream ( args.Stream, int.Parse (daemonargs[daemonargs.Length-1], CultureInfo.InvariantCulture ) ); outstr = inputStream.ReadLine(); outputStream.Close(); inputStream.Close(); netStream.Close(); tcpclient.Close(); } if(outstr!=null && outstr.IndexOf(FOUND)>-1) this.OnVirusFound( new ScanCompletedEventArgs( args.Id, outstr ) ); this.OnItemScanCompleted( new ScanCompletedEventArgs( args.Id, outstr ) ); //reset retry counter _netRetryCount = 0; } catch(Exception ex) { if(ex is SocketException || ex is IOException) { if (_netRetryCount < MAX_NET_RETRY) { //increment retry count and try again _netRetryCount++; StreamScan( args ); } else { //reset retry count log error and return _netRetryCount = 0; if(_logger.IsDebugEnabled) _logger.Error(ex); else _logger.Error(ex.Message); } } else throw; } }