SIP Proxy Server Help

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • chuwfan
    New Member
    • Mar 2007
    • 9

    SIP Proxy Server Help

    Good day every one,
    i just try to develop a sip proxy with mjsip's library,
    now i am facing problem,
    1st, the client is connected to proxy,
    but it can make call (VoIP) to another client,
    the client i using to test is the window messenger 5.1 (with sip support).

    anybody can help me look on the code and try to tell me what is going wrong pls..

    the packet of the client send to proxy just stop at the updateProxingRe sponse method then the client directly shows the connection has be declined by another user. i wonder what is happening.

    Please somebody help..it's urgent for my assignment

    cause the code it's quite long, so someone that willing to help me please give me ur email then i will send it to u, just 1 page of source code. Thanks.

    after that we discuss it here.
  • r035198x
    MVP
    • Sep 2006
    • 13225

    #2
    Originally posted by chuwfan
    Good day every one,
    i just try to develop a sip proxy with mjsip's library,
    now i am facing problem,
    1st, the client is connected to proxy,
    but it can make call (VoIP) to another client,
    the client i using to test is the window messenger 5.1 (with sip support).

    anybody can help me look on the code and try to tell me what is going wrong pls..

    the packet of the client send to proxy just stop at the updateProxingRe sponse method then the client directly shows the connection has be declined by another user. i wonder what is happening.

    Please somebody help..it's urgent for my assignment

    cause the code it's quite long, so someone that willing to help me please give me ur email then i will send it to u, just 1 page of source code. Thanks.

    after that we discuss it here.
    Is the updateProxingRe sponse method too long as well? If not you can just post that here.

    Comment

    • chuwfan
      New Member
      • Mar 2007
      • 9

      #3
      protected Message updateProxingRe sponse(Message resp)
      { printLog("insid e updateProxingRe sponse(resp)",L ogLevel.MEDIUM) ;
      System.out.prin tln("header for response");
      ViaHeader vh=new ViaHeader((Head er)resp.getVias ().getHeaders() .elementAt(0));
      if (vh.getHost().e quals(sip_provi der.getViaAddre ss())) resp.removeViaH eader();
      return resp;
      }


      actually it's can function well before i implements TransactionClie ntListener with the proxy.

      here i paste the updateProxingRe sponse method, the code actually is about 400 lines, is it ok to paste it all here?

      thanks for ur reply.

      Comment

      • r035198x
        MVP
        • Sep 2006
        • 13225

        #4
        Originally posted by chuwfan
        protected Message updateProxingRe sponse(Message resp)
        { printLog("insid e updateProxingRe sponse(resp)",L ogLevel.MEDIUM) ;
        System.out.prin tln("header for response");
        ViaHeader vh=new ViaHeader((Head er)resp.getVias ().getHeaders() .elementAt(0));
        if (vh.getHost().e quals(sip_provi der.getViaAddre ss())) resp.removeViaH eader();
        return resp;
        }


        actually it's can function well before i implements TransactionClie ntListener with the proxy.

        here i paste the updateProxingRe sponse method, the code actually is about 400 lines, is it ok to paste it all here?

        thanks for ur reply.
        I don't think that will help much yet. Can you describe a bit what happens when you run it.

        Comment

        • chuwfan
          New Member
          • Mar 2007
          • 9

          #5
          ok,
          i try to track the flow when i connect with the client and try to call another client.

          what i get is,

          1st it go to the processRequestT oLocalUser method and then make a SipURL url=new SipURL((String) (targets.elemen tAt(i))); object.

          2nd it go to the header part, updateProxingRe quest method, and then go through it and add Record-Route then add ViaHeader.

          3rd it suddenly jump back to the processRequestT oRemoteUA method that i wonder why it go to that method, after that it go to the header part again,

          lastly, it stop at the add ViaHeader part there, then stop.
          then the other side's client didn't get any call from the client1 that calling,
          then the client1 will show that request is decline by client2.

          it seems it never go to the ProcessResponse method and updateProxingRe sponse method at all.
          (when delete the processRequestT oRemoteUA method, it will go to the ProcessResponse method and then to the updateProxingRe sponse method ...then stop right there).

          if i no delete the processRequestT oRemoteUA method, it will just stop at the add viaheader part.

          is it blur from my explanation?
          if still can't imagine, i wish to send you the page of code so that you can try to help me more effectively.

          Thanks.

          Comment

          • chuwfan
            New Member
            • Mar 2007
            • 9

            #6
            it feels like stuck at middle cause by some part of the coding,
            i try so hard to debug it,
            but still can't get it.

            Comment

            • chuwfan
              New Member
              • Mar 2007
              • 9

              #7
              Code:
              public class Proxy extends Registrar implements TransactionClientListener
              {
                 /** Log of processed calls */
                 CallLogger call_logger;
              
                 	/** Transactions state */
                 	protected StatefulProxyState state=null;
              
                    /** SipProvider for client transactions */
                    protected SipProvider sip_provider_client;
              
                    /** SipProvider for server transactions */
                    protected SipProvider sip_provider_server;
              
                    /** Inits the stateful server */
                    private void init()
                    {  sip_provider_client=sip_provider;
                       sip_provider_server=sip_provider;
                       state=new StatefulProxyState();
                 }
              
                 /** Costructs a void Proxy */
                 protected Proxy() {}
              
                 /** Costructs a new Proxy that acts also as location server for registered users. */
                 public Proxy(SipProvider provider, ServerProfile server_profile)
                 {  super(provider,server_profile);
                 		init();
                 		System.out.println("Constructed");
                    if (server_profile.call_log) call_logger=new CallLoggerImpl(SipStack.log_path+"//"+provider.getViaAddress()+"."+provider.getPort()+"_calls.log");
                 }
              
              
                 /** When a new request is received for the local server. */
                 public void processRequestToLocalServer(Message msg)
                 {  printLog("inside processRequestToLocalServer(msg)",LogLevel.MEDIUM);
                    if (msg.isRegister())
                    {  super.processRequestToLocalServer(msg);
                    System.out.println("isRegister(localserver)");
                    }
                    else
                    if (!msg.isAck())
                    {  // send a stateless error response
                       //int result=501; // response code 501 ("Not Implemented")
                       //int result=485; // response code 485 ("Ambiguous");
                       int result=484; // response code 484 ("Address Incomplete");
                       Message resp=MessageFactory.createResponse(msg,result,SipResponses.reasonOf(result),null);
                       sip_provider.sendMessage(resp);
                    }
                 }
              
              
                 /** When a new request message is received for a local user */
                 public void processRequestToLocalUser(Message msg)
                 {  printLog("inside processRequestToLocalUser(msg)",LogLevel.MEDIUM);
              
                    if (server_profile.call_log) call_logger.update(msg);
              
                    if (server_profile.do_proxy_authentication && !msg.isAck() && !msg.isCancel())
                    {  // check message authentication
                       Message err_resp=as.authenticateProxyRequest(msg);
                       if (err_resp!=null)
                       {  sip_provider.sendMessage(err_resp);
                       System.out.println("localuser");
                          return;
                       }
                    }
              
                     TransactionServer ts;
              	        if (msg.isInvite()) ts=new InviteTransactionServer(sip_provider_server,msg,null);
              	        else ts=new TransactionServer(sip_provider_server,msg,null);
              	        //ts.listen();
              
              	        if (server_profile.do_proxy_authentication && !msg.isAck() && !msg.isCancel())
              	        {  // check message authentication
              	           Message err_resp=as.authenticateProxyRequest(msg);
              	           System.out.println("StfulltransactionServer");
              	           if (err_resp!=null)
              	           {  ts.respondWith(err_resp);
              	              return;
              	           }
              	        }
              
              
                    // message targets
                    Vector targets=getTargets(msg);
              
                    if (targets.isEmpty())
                    {
                       SipURL request_uri=msg.getRequestLine().getAddress();
                       System.out.println("request_uri");
                    }
                    if (targets.isEmpty())
                    {  printLog("No target found, message discarded",LogLevel.HIGH);
                       if (!msg.isAck()) sip_provider.sendMessage(MessageFactory.createResponse(msg,404,SipResponses.reasonOf(404),null));
                       return;
                    }
              
                    printLog("message will be forwarded to all user's contacts",LogLevel.MEDIUM);
                    for (int i=0; i<targets.size(); i++)
                    {  SipURL url=new SipURL((String)(targets.elementAt(i)));
                    System.out.println("SIPURL");
                       Message request=new Message(msg);
                       request.removeRequestLine();
                       request.setRequestLine(new RequestLine(msg.getRequestLine().getMethod(),url));
              
                       updateProxingRequest(request);
                       sip_provider.sendMessage(request);
                       TransactionClient tc;
              		 if (msg.isInvite()) tc=new InviteTransactionClient(sip_provider_client,request,this);
              		 else tc=new TransactionClient(sip_provider_client,request,this);
                       state.addClient(ts,tc);
                    }
                 }
              
              
                // When a new request message is received for a remote UA
                   public void processRequestToRemoteUA(Message msg)
                   {  printLog("inside processRequestToRemoteUA(msg)",LogLevel.MEDIUM);
                    System.out.println("request remote UA");
              
                      if (call_logger!=null) call_logger.update(msg);
              
                      if (!server_profile.is_open_proxy)
                      {  // check whether the caller is a local user
                         SipURL from_url=msg.getFromHeader().getNameAddress().getAddress();
                         String from_username=from_url.getUserName();
                         String from_hostaddr=from_url.getHost();
                         String caller=(from_username==null)? from_hostaddr : from_username+"@"+from_hostaddr;
                         if (!location_service.hasUser(caller))
                         {  // but do not filter messages directed to local users
                            SipURL to_url=msg.getToHeader().getNameAddress().getAddress();
                            String to_username=to_url.getUserName();
                            String to_hostaddr=to_url.getHost();
                            String callee=(to_username==null)? to_hostaddr : to_username+"@"+to_hostaddr;
                            if (!location_service.hasUser(callee))
                            {  // both caller and callee are not registered with the local server
                               printLog("both users "+caller+" and "+callee+" are not registered with the local server: proxy denied.",LogLevel.HIGH);
                               sip_provider.sendMessage(MessageFactory.createResponse(msg,503,SipResponses.reasonOf(503),null));
                               return;
                            }
                         }
                      }
              
                      if (server_profile.do_proxy_authentication && !msg.isAck() && !msg.isCancel())
                      {  // check message authentication
                         Message err_resp=as.authenticateProxyRequest(msg);
                         if (err_resp!=null)
                         {  sip_provider.sendMessage(err_resp);
                            return;
                         }
                      }
              
                      updateProxingRequest(msg);
                      sip_provider.sendMessage(msg);
                 }
              
                 /** Processes the Proxy headers of the request.
                   * Such headers are: Via, Record-Route, Route, Max-Forwards, etc. */
                 protected Message updateProxingRequest(Message msg)
                 {  printLog("inside updateProxingRequest(msg)",LogLevel.LOW);
              		System.out.println("header part1");
                    // remove Route if present
                    boolean is_on_route=false;
                    if (msg.hasRouteHeader())
                    {  MultipleHeader mr=msg.getRoutes();
                    System.out.println("X route");
                       SipURL route=(new RouteHeader(mr.getTop())).getNameAddress().getAddress();
                       if (isResponsibleFor(route.getHost(),route.getPort()))
                       {  mr.removeTop();
                          if (mr.size()>0) msg.setRoutes(mr);
                          else msg.removeRoutes();
                          is_on_route=true;
                       }
                    }
                    // add Record-Route?
                    if (server_profile.on_route && msg.isInvite() && !is_on_route)
                    {  SipURL rr_url;
                    	System.out.println("+ route");
                       if (sip_provider.getPort()==SipStack.default_port) rr_url=new SipURL(sip_provider.getViaAddress());
                       else rr_url=new SipURL(sip_provider.getViaAddress(),sip_provider.getPort());
                       if (server_profile.loose_route) rr_url.addLr();
                       RecordRouteHeader rrh=new RecordRouteHeader(new NameAddress(rr_url));
                       msg.addRecordRouteHeader(rrh);
                    }
                    // which protocol?
                    String proto=null;
                    if (msg.hasRouteHeader())
                    {  SipURL route=msg.getRouteHeader().getNameAddress().getAddress();
                    System.out.println("protocol");
                       if (route.hasTransport()) proto=route.getTransport();
                    }
                    else proto=msg.getRequestLine().getAddress().getTransport();
                    if (proto==null) proto=sip_provider.getDefaultTransport();
              
                     // add Via
              	        ViaHeader via=new ViaHeader(proto,sip_provider.getViaAddress(),sip_provider.getPort());
              	        if (sip_provider.isRportSet()) via.setRport();
              	        String branch=sip_provider.pickBranch(msg);
              	        System.out.println("VIA");
              
              	        if (server_profile.loop_detection)
              	        {  String loop_tag=msg.getHeader(Loop_Tag).getValue();
              	           if (loop_tag!=null)
              	           {  msg.removeHeader(Loop_Tag);
              	              branch+=loop_tag;
              	           }
              	        }
              	        via.setBranch(branch);
              	        msg.addViaHeader(via);
              
              	        // decrement Max-Forwards
              	        MaxForwardsHeader maxfwd=msg.getMaxForwardsHeader();
              	        if (maxfwd!=null) maxfwd.decrement();
              	        else maxfwd=new MaxForwardsHeader(SipStack.max_forwards);
              	        msg.setMaxForwardsHeader(maxfwd);
              
              	        // domain name routing
              	        if (server_profile.domain_routing_rules!=null && server_profile.domain_routing_rules.length>0)
              	        {  RequestLine rl=msg.getRequestLine();
              	        System.out.println("domain routing");
              
              	           SipURL request_uri=rl.getAddress();
              	           for (int i=0; i<server_profile.domain_routing_rules.length; i++)
              	           {  RoutingRule rule=(RoutingRule)server_profile.domain_routing_rules[i];
              	              SipURL nexthop=rule.getNexthop(request_uri);
              	              if (nexthop!=null)
              	              {  printLog("domain-based routing: "+rule.toString()+": YES",LogLevel.MEDIUM);
              	                 printLog("target="+nexthop.toString(),LogLevel.MEDIUM);
              	                 rl=new RequestLine(rl.getMethod(),nexthop);
              	                 msg.setRequestLine(rl);
              	                 break;
              	              }
              	              else printLog("prefix-based routing: "+rule.toString()+": NO",LogLevel.MEDIUM);
              	           }
              	        }
              	        return msg;
               }

              Comment

              • chuwfan
                New Member
                • Mar 2007
                • 9

                #8
                continue here... sorry it's so long, hope you won't mind.

                Code:
                   /** When a new response message is received */
                   public void processResponse(Message resp)
                   {  printLog("inside processResponse(msg)",LogLevel.MEDIUM);
                		System.out.println("response message");
                      if(call_logger!=null) call_logger.update(resp);
                
                      updateProxingResponse(resp);
                
                      if (resp.hasViaHeader()) sip_provider.sendMessage(resp);
                      else
                         printLog("no VIA header found: message discarded",LogLevel.HIGH);
                   }
                
                	 /** Sends a server final response */
                	   protected void statefulServerResponse(TransactionServer ts, Message resp)
                	   {  printLog("inside statefulServerResponse(msg)",LogLevel.MEDIUM);
                	   System.out.println("send to server final response");
                	      printLog("Server response: "+resp.getStatusLine().toString(),LogLevel.MEDIUM);
                	      ts.respondWith(resp);
                	   }
                
                	   /** Process provisional response */
                	   protected void processProvisionalResponse(Transaction transaction, Message resp)
                	   {  printLog("inside processProvisionalResponse(t,resp)",LogLevel.MEDIUM);
                	   System.out.println("Cprovisional response");
                	      int code=resp.getStatusLine().getCode();
                	      TransactionServer ts=state.getServer(transaction);
                	      if (ts!=null && code!=100)
                	      {  updateProxingResponse(resp);
                	         if (resp.hasViaHeader()) ts.respondWith(resp);
                	      }
                	   }
                
                	   /** Process failure response */
                	   protected void processFailureResponse(Transaction transaction, Message resp)
                	   {  printLog("inside processFailureResponse(t,resp)",LogLevel.MEDIUM);
                	   System.out.println("failured response");
                	      TransactionServer ts=state.getServer(transaction);
                	      state.removeClient(transaction);
                	      if (ts==null) return;
                	      if (!state.hasServer(ts)) return;
                	      // updates the non-2xx final response
                	      state.setFinalResponse(ts,resp);
                	      // if there are no more pending clients, sends the final response
                	      HashSet clients=state.getClients(ts);
                	      if (clients.isEmpty())
                	      {  printLog("only this tr_client remained: send the response",LogLevel.LOW);
                	         resp=state.getFinalResponse(ts);
                	         updateProxingResponse(resp);
                	         if (resp.hasViaHeader()) ts.respondWith(resp);
                	         state.removeServer(ts);
                	      }
                	   }
                
                	   /** Process success response */
                	   protected void processSuccessResponse(Transaction transaction, Message resp)
                	   {  printLog("inside processSuccessResponse(t,resp)",LogLevel.MEDIUM);
                	   System.out.println("Success response");
                	      TransactionServer ts=state.getServer(transaction);
                	      state.removeClient(transaction);
                	      if (ts==null) return;
                	      updateProxingResponse(resp);
                	      if (resp.hasViaHeader())
                	      {  ts.respondWith(resp);
                	         if (!state.hasServer(ts)) return;
                	         //else
                	         // cancel all other pending transaction clients
                	         HashSet clients=state.getClients(ts);
                	         //printLog("Cancel pending clients..",LogLevel.LOW);
                	         //if (clients==null) return;
                	         printLog("Cancelling "+clients.size()+" pending clients",LogLevel.LOW);
                	         for (Iterator i=clients.iterator(); i.hasNext(); )
                	         {  Transaction tc=(Transaction)i.next();
                	            Message cancel=MessageFactory.createCancelRequest(tc.getRequestMessage());
                	            TransactionClient tr_cancel=new TransactionClient(sip_provider_server,cancel,null);
                	            tr_cancel.request();
                	         }
                	         state.removeServer(ts);
                	      }
                	   }
                
                
                	   /** Process timeout */
                	   protected void processTimeout(Transaction transaction)
                	   {  printLog("inside processTimeout(t)",LogLevel.MEDIUM);
                	   System.out.println("Time out processing");
                	      TransactionServer ts=state.getServer(transaction);
                	      state.removeClient(transaction);
                	      if (ts==null) return;
                	      HashSet clients=(HashSet)state.getClients(ts);
                	      if (clients==null) return;
                	      if (clients.isEmpty())
                	      {  printLog("DEBUG: responding..",LogLevel.LOW);
                	         //printLog("DEBUG:\r\n"+state.getFinalResponse(ts),LogLevel.LOW);
                	         Message resp=state.getFinalResponse(ts);
                	         updateProxingResponse(resp);
                	         if (resp.hasViaHeader()) statefulServerResponse(ts,resp);
                	         state.removeServer(ts);
                	      }
                   }
                
                   /** Processes the Proxy headers of the response.
                     * Such headers are: Via, .. */
                   protected Message updateProxingResponse(Message resp)
                   {  printLog("inside updateProxingResponse(resp)",LogLevel.MEDIUM);
                   System.out.println("header for response");
                      ViaHeader vh=new ViaHeader((Header)resp.getVias().getHeaders().elementAt(0));
                      if (vh.getHost().equals(sip_provider.getViaAddress())) resp.removeViaHeader();
                      return resp;
                   }
                
                
                    // ******************* TransactionClient callback methods *******************
                
                      /** When the TransactionClient is in "Proceeding" state and receives a new 1xx response */
                      public void onTransProvisionalResponse(TransactionClient transaction, Message resp)
                      {  processProvisionalResponse(transaction,resp);
                      }
                
                      /** When the TransactionClient goes into the "Completed" state, receiving a failure response */
                      public void onTransFailureResponse(TransactionClient transaction, Message resp)
                      {  processFailureResponse(transaction,resp);
                      }
                
                      /** When an TransactionClient goes into the "Terminated" state, receiving a 2xx response */
                      public void onTransSuccessResponse(TransactionClient transaction, Message resp)
                      {  processSuccessResponse(transaction,resp);
                      }
                
                      /** When the TransactionClient goes into the "Terminated" state, caused by transaction timeout */
                      public void onTransTimeout(TransactionClient transaction)
                      {  processTimeout(transaction);
                   }
                
                   // ****************************** Logs *****************************
                
                   /** Adds a new string to the default Log */
                   private void printLog(String str, int level)
                   {  if (log!=null)
                   {
                	   log.println("StatefulProxy: "+str,level+SipStack.LOG_LEVEL_UA);
                	   log.println("Proxy: "+str,level+SipStack.LOG_LEVEL_UA);
                   }
                   }
                
                
                   // ****************************** MAIN *****************************
                
                   /** The main method. */
                   public static void main(String[] args)
                   {
                
                      String file=null;
                      boolean prompt_exit=false;
                
                      for (int i=0; i<args.length; i++)
                      {  if (args[i].equals("-f") && args.length>(i+1))
                         {  file=args[++i];
                            continue;
                         }
                      }
                
                      SipStack.init(file);
                      SipProvider sip_provider=new SipProvider(file);
                      ServerProfile server_profile=new ServerProfile(file);
                
                      System.out.println("Start");
                
                      new Proxy(sip_provider,server_profile);
                
                      System.out.println("Connected");
                
                   }
                
                }
                Thanks for ur help..

                Comment

                • chuwfan
                  New Member
                  • Mar 2007
                  • 9

                  #9
                  Anybody?
                  Please try to help me.

                  Comment

                  Working...