package local.server; import org.zoolu.net.SocketAddress; import org.zoolu.sip.address.*; import org.zoolu.sip.provider.*; import org.zoolu.tools.Configure; import org.zoolu.tools.Parser; import java.io.*; import java.net.InetAddress; import java.util.Vector; /** ServerProfile maintains the server configuration. */ public class ServerProfile extends Configure { /** The default configuration file */ private static String config_file="mjsip.cfg"; // ********************* server configurations ******************** /** The domain names that the server administers. * <p>It lists the domain names for which the Location Service maintains user bindings. * <br>Use 'auto-configuration' for automatic configuration of the domain name. */ public String[] domain_names=null; /** Whether consider any port as valid local domain port * (regardless which sip port is used). */ public boolean domain_port_any=false; /** Whether the Server should act as Registrar (i.e. respond to REGISTER requests). */ public boolean is_registrar=true; /** Maximum expires time (in seconds). */ public int expires=3600; /** Whether the Registrar can register new users (i.e. REGISTER requests from unregistered users). */ public boolean register_new_users=true; /** Whether the Server relays requests for (or to) non-local users. */ public boolean is_open_proxy=true; /** The type of location service. * You can specify the location service type (e.g. local, ldap, radius, mysql) * or the class name (e.g. local.server.LocationServiceImpl). */ public String location_service="local"; /** The name of the location DB. */ public String location_db="users.db"; /** Whether location DB has to be cleaned at startup. */ public boolean clean_location_db=false; /** Whether the Server authenticates local users. */ public boolean do_authentication=false; /** Whether the Proxy authenticates users. */ public boolean do_proxy_authentication=false; /** The authentication scheme. * You can specify the authentication scheme name (e.g. Digest, AKA, etc.) * or the class name (e.g. local.server.AuthenticationServerImpl). */ public String authentication_scheme="Digest"; /** The authentication realm. * If not defined or equal to 'NONE' (default), the used via address is used instead. */ public String authentication_realm=null; /** The type of authentication service. * You can specify the authentication service type (e.g. local, ldap, radius, mysql) * or the class name (e.g. local.server.AuthenticationServiceImpl). */ public String authentication_service="local"; /** The name of the authentication DB. */ public String authentication_db="aaa.db"; /** Whether maintaining a complete call log. */ public boolean call_log=false; /** Whether the server should stay in the signaling path (uses Record-Route/Route) */ public boolean on_route=false; /** Whether implementing the RFC3261 Loose Route (or RFC2543 Strict Route) rule */ public boolean loose_route=true; /** Whether checking for loops before forwarding a request (Loop Detection). In RFC3261 it is optional. */ public boolean loop_detection=true; /** Array of RoutingRules based on pairs of username or phone prefix and corresponding nexthop address. * It provides static rules for routing number-based SIP-URL the server is responsible for. * Use "default" (or "*") as default prefix. * Example, request URL sip:01234567@zoopera.com received by a server responsible for domain name 'zoopera.com'. * phone_routing_rules={prefix=0123,nexthop=127.0.0.2:7002} {prefix=*,nexthop=127.0.0.3:7003} */ public RoutingRule[] phone_routing_rules=null; /** Array of RoutingRules based on pairs of destination domain and corresponding nexthop address. * It provides static rules for routing domain-based SIP-URL the server is NOT responsible for. * It make the server acting (also) as 'Interrogating' Proxy, i.e. I-CSCF in the 3G networks. * Example, domain_routing_rules={domain=wonderland.net,nexthop=neverland.net:5060} */ public RoutingRule[] domain_routing_rules=null; // ************************** costructors ************************* /** Costructs a new ServerProfile */ public ServerProfile(String file) { // load SipStack first if (!SipStack.isInit()) SipStack.init(); // load configuration loadFile(file); // post-load manipulation if (authentication_realm!=null && authentication_realm.equals(Configure.NONE)) authentication_realm=null; if (domain_names==null) domain_names=new String[0]; if (phone_routing_rules==null) phone_routing_rules=new RoutingRule[0]; if (domain_routing_rules==null) domain_routing_rules=new RoutingRule[0]; } /** Parses a single line of the file */ protected void parseLine(String line) { String attribute; Parser par; int index=line.indexOf("="); if (index>0) { attribute=line.substring(0,index).trim(); par=new Parser(line,index+1); } else { attribute=line; par=new Parser(""); } if (attribute.equals("is_registrar")) { is_registrar=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("expires")) { expires=par.getInt(); return; } if (attribute.equals("register_new_users")) { register_new_users=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("is_open_proxy")) { is_open_proxy=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("location_service")) { location_service=par.getString(); return; } if (attribute.equals("location_db")) { location_db=par.getString(); return; } if (attribute.equals("clean_location_db")) { clean_location_db=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("do_authentication")) { do_authentication=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("do_proxy_authentication")) { do_proxy_authentication=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("authentication_scheme")) { authentication_scheme=par.getString(); return; } if (attribute.equals("authentication_realm")) { authentication_realm=par.getString(); return; } if (attribute.equals("authentication_service")) { authentication_service=par.getString(); return; } if (attribute.equals("authentication_db")) { authentication_db=par.getString(); return; } if (attribute.equals("call_log")) { call_log=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("on_route")) { on_route=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("loose_route")) { loose_route=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("loop_detection")) { loop_detection=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("domain_port_any")) { domain_port_any=(par.getString().toLowerCase().startsWith("y")); return; } if (attribute.equals("domain_names")) { char[] delim={' ',','}; Vector aux=new Vector(); do { String domain=par.getWord(delim); if (domain.equals(SipProvider.AUTO_CONFIGURATION)) { // auto configuration String host_addr=null; String host_name=null; try { InetAddress address=java.net.InetAddress.getLocalHost(); host_addr=address.getHostAddress(); host_name=address.getHostName(); } catch (java.net.UnknownHostException e) { if (host_addr==null) host_addr="127.0.0.1"; if (host_name==null) host_name="localhost"; } aux.addElement(host_addr); aux.addElement(host_name); } else { // manual configuration aux.addElement(domain); } } while (par.hasMore()); domain_names=new String[aux.size()]; for (int i=0; i<aux.size(); i++) domain_names[i]=(String)aux.elementAt(i); return; } if (attribute.equals("phone_routing_rules")) { char[] delim={' ',',','}'}; Vector aux=new Vector(); par.goTo('{'); while (par.hasMore()) { par.goTo("prefix").skipN(6).goTo('=').skipChar(); String prefix=par.getWord(delim); if (prefix.equals("*")) prefix=PrefixRoutingRule.DEFAULT_PREFIX; par.goTo("nexthop").skipN(7).goTo('=').skipChar(); String nexthop=par.getWord(delim); aux.addElement(new PrefixRoutingRule(prefix,new SocketAddress(nexthop))); par.goTo('{'); } phone_routing_rules=new RoutingRule[aux.size()]; for (int i=0; i<aux.size(); i++) phone_routing_rules[i]=(RoutingRule)aux.elementAt(i); return; } if (attribute.equals("domain_routing_rules")) { char[] delim={' ',',','}'}; Vector aux=new Vector(); par.goTo('{'); while (par.hasMore()) { par.goTo("domain").skipN(6).goTo('=').skipChar(); String prefix=par.getWord(delim); par.goTo("nexthop").skipN(7).goTo('=').skipChar(); String nexthop=par.getWord(delim); aux.addElement(new DomainRoutingRule(prefix,new SocketAddress(nexthop))); par.goTo('{'); } domain_routing_rules=new RoutingRule[aux.size()]; for (int i=0; i<aux.size(); i++) domain_routing_rules[i]=(RoutingRule)aux.elementAt(i); return; } } /** Converts the entire object into lines (to be saved into the config file) */ protected String toLines() { // currently not implemented.. return toString(); } /** Gets a String value for this object */ public String toString() { return domain_names.toString(); } }