/* * TurnServer, the OpenSource Java Solution for TURN protocol. Maintained by the * Jitsi community (http://jitsi.org). * * Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jitsi.turnserver.stack; import org.ice4j.*; /** * This class is an implementation of Permissions in TURN protocol. * * @author Aakash Garg * */ public class Permission { /** * The maximum lifetime allowed for a Permission. */ public static final long MAX_LIFETIME = 300 * 1000; /** * The IP address of the peer for which to create Permission. */ private TransportAddress ipAddress; /** * The time in milliseconds when the Permission will expire. */ private long expirationTime = -1; /** * Determines whether or not the Permission has expired. */ private boolean expired = false; /** * @param ipAddress contains the peer IP address and transport protocol to * be assigned. The port value is ignored. */ public Permission(TransportAddress ipAddress) { this.setIpAddress(ipAddress); this.setLifetime(Permission.MAX_LIFETIME); } /** * @param ipAddress contains the peer IP address and transport protocol to * be assigned. The port value is ignored. * @param lifetime the lifetime of permission. */ public Permission(TransportAddress ipAddress, long lifetime) { this.setIpAddress(ipAddress); this.setLifetime(lifetime); } /** * @param ipAddress contains the peer IP address in String format. * @param lifetime the lifetime of permission. */ public Permission(String ipAddress, long lifetime) { this.setIpAddress(ipAddress); this.setLifetime(lifetime); } /** * @return the ipAddress of the Permission as a TransportAddress. */ public TransportAddress getIpAddress() { return ipAddress; } /** * @return the ipAddress as a String. */ public String getIpAddressString() { return this.getIpAddress().getHostAddress(); } /** * @param ipAddress the ipAddress of the peer for which to create * Permission. */ public void setIpAddress(TransportAddress ipAddress) { this.ipAddress = new TransportAddress(ipAddress.getHostAddress(), 0, ipAddress.getTransport()); } /** * @param ipAddress the ipAddress as String of the peer for which to create * Permission. */ public void setIpAddress(String ipAddress) { this.ipAddress = new TransportAddress(ipAddress, 0, Transport.UDP); } /** * Returns the lifetime associated with this Permission. * If the Permission is expired it returns 0. */ public long getLifetime() { if(!isExpired()) { return (this.expirationTime-System.currentTimeMillis()); } else { return 0; } } /** * Sets the time to expire in milli-seconds for this Permission. * Max lifetime can be Permission.MAX_LIFEIME. * * @param lifetime the lifetime for this Permission. */ public void setLifetime(long lifetime) { synchronized(this) { this.expirationTime = System.currentTimeMillis() + Math.min(lifetime*1000, Permission.MAX_LIFETIME); } } /** * Refreshes the permission with the MAX_LIFETIME value. */ public void refresh() { this.setLifetime(Permission.MAX_LIFETIME); } /** * refreshes the permission with given lifetime value. * @param lifetime the required lifetime of permission. */ public void refresh(int lifetime) { this.setLifetime(lifetime); } /** * Start the Permission. This launches the countdown to the moment the * Permission would expire. */ public synchronized void start() { synchronized(this) { if (expirationTime == -1) { expired = false; expirationTime = MAX_LIFETIME + System.currentTimeMillis(); } else { throw new IllegalStateException( "Permission has already been started!"); } } } /** * Determines whether this <tt>Permission</tt> is expired now. * * @return <tt>true</tt> if this <tt>Permission</tT> is expired * now; otherwise, <tt>false</tt> */ public boolean isExpired() { return isExpired(System.currentTimeMillis()); } /** * Expires the Permission. Once this method is called the Permission is * considered terminated. */ public synchronized void expire() { expired = true; /* * TurnStack has a background Thread running with the purpose of * removing expired Permissions. */ } /** * Determines whether this <tt>Permission</tt> will be expired at * a specific point in time. * * @param now the time in milliseconds at which the <tt>expired</tt> state * of this <tt>Permission</tt> is to be returned * @return <tt>true</tt> if this <tt>Permission</tt> will be * expired at the specified point in time; otherwise, <tt>false</tt> */ public synchronized boolean isExpired(long now) { if (expirationTime == -1) return false; else if (expirationTime < now) return true; else return expired; } /* * The permission is uniquely identified by its IP address, so hashCode is * calculated on the IP address only. */ @Override public int hashCode() { return ipAddress.getHostAddress().hashCode(); } /* * Two Permissions are equal if their associated IP address, lifetime and * transport protocol are same. */ @Override public boolean equals(Object obj) { if (!(obj instanceof Permission)) { return false; } Permission other = (Permission) obj; if (ipAddress == null) { if (other.ipAddress != null) { return false; } } else if (ipAddress.getHostAddress().compareTo( other.ipAddress.getHostAddress()) != 0) { return false; } if (expirationTime != other.expirationTime) { return false; } return true; } @Override public String toString() { return "Permission [" + (ipAddress != null ? "ipAddress=" + ipAddress : "") + "]"; } }