/// <summary> /// Request handler. /// </summary> /// <param name="sender">The serveragent object.</param> /// <param name="eventArgs">Request parameters.</param> public virtual void OnRequest(object sender, RequestReceivedEventArgs eventArgs) { Request request = eventArgs.Request; bool requestIsAllowed = false; bool addedToAllowList = false; string fromUserAtHost; string toUserAtHost; Header header = request.AllHeaders.FindFirst(Header.StandardHeaderType.From); fromUserAtHost = Utils.UriParser.GetUserAtHost(header.Value); header = request.AllHeaders.FindFirst(Header.StandardHeaderType.To); toUserAtHost = Utils.UriParser.GetUserAtHost(header.Value); // // Check the request origin and carry out the appropriate action. // AuthenticationInfo authenticationInfo = (AuthenticationInfo)request.AuthenticationInfo; if (authenticationInfo.Origin == AuthenticationInfo.MessageOrigin.NetworkExternal) { // // Get the From domain. // string fromDomain = Utils.UriParser.GetHost(fromUserAtHost).ToLower(); // // See if this domain has been validated already. // lock (this.SyncRoot) { if (allowList.Contains(fromDomain)) { // // This is a validated domain. It can show up here if we // added this in another thread and this has not been picked up // in SPL. // requestIsAllowed = true; } } if (!requestIsAllowed) { LogEntry logEntry = new LogEntry(fromUserAtHost, toUserAtHost, fromDomain); lock (externalEdgeLog.SyncRoot) { externalEdgeLog.Log(logEntry); } } } else { // We should have only internal here - the SPL script should not be // dispatching the other cases here. Debug.Assert(authenticationInfo.Origin == AuthenticationInfo.MessageOrigin.NetworkInternal); // // Get the To domain. // string toDomain = Utils.UriParser.GetHost(toUserAtHost).ToLower(); // // See if this domain has been validated already. // lock (this.SyncRoot) { if (allowList.Contains(toDomain)) { // // This is a validated domain. It can show up here if we // added this in another thread and this has not been picked up // in SPL. // requestIsAllowed = true; } else { // // Policy implementation. Put action to be carried out for unknown // internal domains here. // // // Check whether we are allowed to add this entry automatically. // if (config.ActionForUnknownDomainFromInternalEdge == Config.ActionAutoAdd) { if (currentDomains + 1 < config.MaxDomainsInEnhancedAllowList) { allowList.Add(toDomain, null); currentDomains += 1; addedToAllowList = true; requestIsAllowed = true; } else { RaiseConfigFileFullEvent(); } } } } if (addedToAllowList) { // // This entry was added to the global allow list and hence we need to add // this to the SPL script flat file. // try { InternalAppendDomainToEnhancedAllowListFile(toDomain); } catch (Exception e) { // Failed to open or write to allow list. lock (this.SyncRoot) { allowList.Remove(toDomain); currentDomains -= 1; addedToAllowList = false; requestIsAllowed = false; } RaiseConfigFileWriteFailureEvent(e.Message); } if (addedToAllowList) { // // Log that we added this entry as well. // LogEntry logEntry = new AllowListLogEntry(fromUserAtHost, toUserAtHost, toDomain); lock (internalEdgeLog.SyncRoot) { internalEdgeLog.Log(logEntry); } } } if (!requestIsAllowed) { LogEntry logEntry = new LogEntry(fromUserAtHost, toUserAtHost, toDomain); lock (internalEdgeLog.SyncRoot) { internalEdgeLog.Log(logEntry); } } } if (requestIsAllowed) { // // Mark the request as simple proxy. This will turn on // performance optimizations that would otherwise be not // possible. // request.SimpleProxy = true; eventArgs.ServerTransaction.EnableForking = false; ClientTransaction ct = eventArgs.ServerTransaction.CreateBranch(); ct.SendRequest(request); } else { Response localResponse = request.CreateResponse(403); eventArgs.ServerTransaction.SendResponse(localResponse); } }
/// <summary> /// This function receives SIP requests, updates /// session state variables, and proxies the request /// to the default request uri /// </summary> /// <remarks> /// The request handler's name must be the name of the /// function that is given in the SPL Dispatch function /// for SIP requests. /// </remarks> /// <param name="sender">not used</param> /// <param name="e">the request state</param> public void RequestHandler(object sender, RequestReceivedEventArgs e) { /* If this is a SIP INVITE, then create an entry * in the session state table for this call-id. * A session is established, when an ACK for this * call-id is received. */ Request request = e.Request; if (request.StandardMethod == Request.StandardMethodType.Invite) { ///extract the call-id and create session state Header callIdHeader = request.AllHeaders.FindFirst("Call-ID"); if (callIdHeader != null) { Session newSession = new Session(); newSession.State = Session.States.Initializing; newSession.CallId = callIdHeader.Value; lock (sessionStateTable.SyncRoot) { sessionStateTable[callIdHeader.Value] = newSession; } } } else if (request.StandardMethod == Request.StandardMethodType.Ack) { ///extract the call-id and update session state, ignore errors Header callIdHeader = request.AllHeaders.FindFirst("Call-ID"); if (callIdHeader != null) { Session session = sessionStateTable[callIdHeader.Value] as Session; if (session != null) { session.State = Session.States.Established; statistics.Update(true /* new session */); } } } ///update other counters statistics.Update(request.StandardMethod); Header fromHeader = request.AllHeaders.FindFirst("From"); Header toHeader = request.AllHeaders.FindFirst("To"); statistics.Update(SipUriParser.GetUserAtHost(fromHeader.Value)); statistics.Update(SipUriParser.GetUserAtHost(toHeader.Value)); ///notify the state change this.StateChangeListeners(e); ///We will not be forking, and marking this explicitly ///allows ServerAgent to optimize message proxying. e.ServerTransaction.EnableForking = false; ///we are done with state management, proxy ClientTransaction ct = e.ServerTransaction.CreateBranch(); if (SimpleProxy) { // Setting SimpleProxy to true will turn on performance // optimizations during message proxying. request.SimpleProxy = true; } ///Add a header if requested by user. if (AddHeader) { Header h = new Header(SipSnoopHeaderName, SipSnoopHeaderValue); request.AllHeaders.Add(h); } ///Modify To header if requested by user by adding a parameter. if (ModifyToHeader) { NameValueCollection toParamColl = toHeader.Parameters; toParamColl.Set(SipSnoopParamName, SipSnoopParamValue); toHeader.Parameters = toParamColl; } ct.SendRequest(e.Request); return; }