All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gov.nist.javax.sip.Utils Maven / Gradle / Ivy

There is a newer version: 1.3.0-91
Show newest version
/*
 * Conditions Of Use
 *
 * This software was developed by employees of the National Institute of
 * Standards and Technology (NIST), an agency of the Federal Government.
 * Pursuant to title 15 Untied States Code Section 105, works of NIST
 * employees are not subject to copyright protection in the United States
 * and are considered to be in the public domain.  As a result, a formal
 * license is not needed to use the software.
 *
 * This software is provided by NIST as a service and is expressly
 * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
 * AND DATA ACCURACY.  NIST does not warrant or make any representations
 * regarding the use of the software or the results thereof, including but
 * not limited to the correctness, accuracy, reliability or usefulness of
 * the software.
 *
 * Permission to use this software is contingent upon your acceptance
 * of the terms of this agreement
 *
 *
 */
/*******************************************************************************
 * Product of NIST/ITL Advanced Networking Technologies Division (ANTD).       *
 *******************************************************************************/
/*
 * Contributions and bug fixes by Vladimir Ralev
 */
package gov.nist.javax.sip;

import gov.nist.javax.sip.header.Via;
import gov.nist.javax.sip.message.SIPResponse;

import java.security.MessageDigest;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * A few utilities that are used in various places by the stack. This is used to
 * convert byte arrays to hex strings etc. Generate tags and branch identifiers
 * and odds and ends.
 *
 * @author mranga
 * @version 1.2 $Revision: 1.24 $ $Date: 2010-10-28 03:20:31 $
 */
public class Utils implements UtilsExt {
	
	private static int digesterPoolsSize = 20;

    private static MessageDigest[] digesterPool = new MessageDigest[digesterPoolsSize];

    private static java.util.Random rand;

    private static long counter = 0;

    private static int callIDCounter;

    private static String signature ;

    private static Utils instance = new Utils();


    /**
     * to hex converter
     */
    private static final char[] toHex = { '0', '1', '2', '3', '4', '5', '6',
            '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    static {
        try {
        	for(int q=0; q> 4) & 0x0F];
            c[pos++] = toHex[b[i] & 0x0f];
        }
        return new String(c);
    }

    /**
     * Put quotes around a string and return it.
     * Any " characters appearing in str are escaped
     *
     * @return a quoted string
     * @param str
     *            string to be quoted
     */
    public static String getQuotedString(String str) {
        return '"' + str.replace( "\"", "\\\"" ) + '"';
    }

    /**
     * Squeeze out all white space from a string and return the reduced string.
     *
     * @param input
     *            input string to sqeeze.
     * @return String a reduced string.
     */
    protected static String reduceString(String input) {
        String newString = input.toLowerCase();
        int len = newString.length();
        String retval = "";
        for (int i = 0; i < len; i++) {
            if (newString.charAt(i) == ' ' || newString.charAt(i) == '\t')
                continue;
            else
                retval += newString.charAt(i);
        }
        return retval;
    }

    /**
     * Converts the characters in this String to upper case.
     * @param str the String to convert. Using english as default
     * as header strings are in English.
     * Resolves a bug in parsing and uppercase when default locale is set
     * to Turkish.
     * @return  the String, converted to uppercase.
     */
    public static String toUpperCase(String str)
    {
        return str.toUpperCase(Locale.ENGLISH);
    }

    /**
     * Generate a call identifier. This is useful when we want to generate a
     * call identifier in advance of generating a message.
     */
    public String generateCallIdentifier(String address) {
    	long random = rand.nextLong();
    	int hash = (int) Math.abs(random%digesterPoolsSize);
    	MessageDigest md = digesterPool[hash];
    	
    	synchronized (md) {
    		String date = Long.toString(System.nanoTime() + System.currentTimeMillis() + callIDCounter++
    				+ random);
    		byte cid[] = md.digest(date.getBytes());

    		String cidString = Utils.toHexString(cid);
    		return cidString + "@" + address;
    	}
    }

    /**
     * Generate a tag for a FROM header or TO header. Just return a random 4
     * digit integer (should be enough to avoid any clashes!) Tags only need to
     * be unique within a call.
     *
     * @return a string that can be used as a tag parameter.
     *
     * synchronized: needed for access to 'rand', else risk to generate same tag
     * twice
     */
    public synchronized String generateTag() {

            return Integer.toHexString(rand.nextInt());

    }

    /**
     * Generate a cryptographically random identifier that can be used to
     * generate a branch identifier.
     *
     * @return a cryptographically random gloablly unique string that can be
     *         used as a branch identifier.
     */
    public String generateBranchId() {
    	//
    	long num = rand.nextLong() + Utils.counter++  + System.currentTimeMillis() + System.nanoTime();
    	int hash = (int) Math.abs(num%digesterPoolsSize);
    	MessageDigest digester = digesterPool[hash];
    	synchronized(digester) {
    		byte bid[] = digester.digest(Long.toString(num).getBytes());
    		// prepend with a magic cookie to indicate we are bis09 compatible.
    		return SIPConstants.BRANCH_MAGIC_COOKIE + "-"
    		+ this.signature + "-" + Utils.toHexString(bid);
    	}
    }

    public boolean responseBelongsToUs(SIPResponse response) {
        Via topmostVia = response.getTopmostVia();
        String branch = topmostVia.getBranch();
        return branch != null && branch.startsWith(
                   SIPConstants.BRANCH_MAGIC_COOKIE + "-" + this.signature);
    }

    public static String getSignature() {
        return signature;
    }

    public static void main(String[] args) {
    	final HashSet branchIds = new HashSet();
    	Executor e = Executors.newFixedThreadPool(100);
    	for(int q=0; q<100; q++) {
    		e.execute(new Runnable() {
				
				
				public void run() {
					for (int b = 0; b < 1000000; b++) {
		    			String bid = Utils.getInstance().generateBranchId();
		    			if (branchIds.contains(bid)) {
		    				throw new RuntimeException("Duplicate Branch ID");
		    			} else {
		    				branchIds.add(bid);
		    			}
		    		}
				}
			});
    	}
    	System.out.println("Done!!");

    }



}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy