Commit ee43a017 authored by Matt Tucker's avatar Matt Tucker Committed by matt

Removed use of UnauthorizedException, cleaned up connection logic, start of...

Removed use of UnauthorizedException, cleaned up connection logic, start of work on TLS, Javadoc improvements.


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@1200 b35dd754-fafc-0310-a699-88a17e54d16e
parent 576e8962
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
import org.jivesoftware.messenger.auth.UnauthorizedException;
/** /**
* Interface to handle packets delivered by Channels. * Interface to handle packets delivered by Channels.
...@@ -25,8 +25,7 @@ public interface ChannelHandler<T extends Packet> { ...@@ -25,8 +25,7 @@ public interface ChannelHandler<T extends Packet> {
* Process an XMPP packet. * Process an XMPP packet.
* *
* @param packet a packet to process. * @param packet a packet to process.
* @throws UnauthorizedException thrown if the packet's sender lacks authorization * @throws UnauthorizedException if not allowed to process the packet.
* to access resources (will result in uniform unauthorized access error reply).
* @throws PacketException thrown if the packet is malformed (results in the sender's * @throws PacketException thrown if the packet is malformed (results in the sender's
* session being shutdown). * session being shutdown).
*/ */
......
...@@ -16,6 +16,7 @@ import org.jivesoftware.messenger.auth.UnauthorizedException; ...@@ -16,6 +16,7 @@ import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.User; import org.jivesoftware.messenger.user.User;
import org.jivesoftware.messenger.user.UserManager; import org.jivesoftware.messenger.user.UserManager;
import org.jivesoftware.messenger.user.UserNotFoundException; import org.jivesoftware.messenger.user.UserNotFoundException;
import org.jivesoftware.messenger.net.SocketConnection;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
...@@ -37,6 +38,13 @@ public class ClientSession extends Session { ...@@ -37,6 +38,13 @@ public class ClientSession extends Session {
private static final String ETHERX_NAMESPACE = "http://etherx.jabber.org/streams"; private static final String ETHERX_NAMESPACE = "http://etherx.jabber.org/streams";
private static final String FLASH_NAMESPACE = "http://www.jabber.com/streams/flash"; private static final String FLASH_NAMESPACE = "http://www.jabber.com/streams/flash";
private static final String TLS_NAMESPACE = "urn:ietf:params:xml:ns:xmpp-tls";
/**
* Version of the XMPP spec supported as MAJOR_VERSION.MINOR_VERSION (e.g. 1.0).
*/
private static final int MAJOR_VERSION = 0;
private static final int MINOR_VERSION = 0;
/** /**
* The authentication token for this session. * The authentication token for this session.
...@@ -53,9 +61,9 @@ public class ClientSession extends Session { ...@@ -53,9 +61,9 @@ public class ClientSession extends Session {
private int conflictCount = 0; private int conflictCount = 0;
/** /**
* Returns a newly created session between the server and a client. The session will be created * Returns a newly created session between the server and a client. The session will
* and returned only if correct Name/Prefix (i.e. 'stream' or 'flash') and Namespace were * be created and returned only if correct name/prefix (i.e. 'stream' or 'flash')
* provided by the client. * and namespace were provided by the client.
* *
* @param serverName the name of the server where the session is connecting to. * @param serverName the name of the server where the session is connecting to.
* @param reader the reader that is reading the provided XML through the connection. * @param reader the reader that is reading the provided XML through the connection.
...@@ -63,37 +71,73 @@ public class ClientSession extends Session { ...@@ -63,37 +71,73 @@ public class ClientSession extends Session {
* @return a newly created session between the server and a client. * @return a newly created session between the server and a client.
*/ */
public static Session createSession(String serverName, XPPPacketReader reader, public static Session createSession(String serverName, XPPPacketReader reader,
Connection connection) throws XmlPullParserException, UnauthorizedException, SocketConnection connection) throws XmlPullParserException, UnauthorizedException,
IOException { IOException
{
XmlPullParser xpp = reader.getXPPParser(); XmlPullParser xpp = reader.getXPPParser();
Session session;
boolean isFlashClient = xpp.getPrefix().equals("flash"); boolean isFlashClient = xpp.getPrefix().equals("flash");
connection.setFlashClient(isFlashClient);
// Conduct error checking, the opening tag should be 'stream' // Conduct error checking, the opening tag should be 'stream'
// in the 'etherx' namespace // in the 'etherx' namespace
if (!xpp.getName().equals("stream") && !isFlashClient) { if (!xpp.getName().equals("stream") && !isFlashClient) {
throw new XmlPullParserException(LocaleUtils.getLocalizedString("admin.error.bad-stream")); throw new XmlPullParserException(
LocaleUtils.getLocalizedString("admin.error.bad-stream"));
} }
if (!xpp.getNamespace(xpp.getPrefix()).equals(ETHERX_NAMESPACE) && if (!xpp.getNamespace(xpp.getPrefix()).equals(ETHERX_NAMESPACE) &&
!(isFlashClient && xpp.getNamespace(xpp.getPrefix()).equals(FLASH_NAMESPACE))) { !(isFlashClient && xpp.getNamespace(xpp.getPrefix()).equals(FLASH_NAMESPACE)))
throw new XmlPullParserException(LocaleUtils.getLocalizedString("admin.error.bad-namespace")); {
throw new XmlPullParserException(LocaleUtils.getLocalizedString(
"admin.error.bad-namespace"));
} }
// Create a ClientSession for this user // Default language is English ("en").
session = SessionManager.getInstance().createClientSession(connection);
// TODO Should we keep the language requested by the client in the session so that
// future messages to the client may use the correct resource bundle? So far we are
// only answering the same language specified by the client (if any) or if none then
// answer a default language
String language = "en"; String language = "en";
// Default to a version of "0.0". Clients written before the XMPP 1.0 spec may
// not report a version in which case "0.0" should be assumed (per rfc3920
// section 4.4.1).
int majorVersion = 0;
int minorVersion = 0;
for (int i = 0; i < xpp.getAttributeCount(); i++) { for (int i = 0; i < xpp.getAttributeCount(); i++) {
if ("lang".equals(xpp.getAttributeName(i))) { if ("lang".equals(xpp.getAttributeName(i))) {
language = xpp.getAttributeValue(i); language = xpp.getAttributeValue(i);
} }
if ("version".equals(xpp.getAttributeName(i))) {
try {
String [] versionString = xpp.getAttributeValue(i).split("\\.");
majorVersion = Integer.parseInt(versionString[0]);
minorVersion = Integer.parseInt(versionString[1]);
}
catch (Exception e) {
Log.error(e);
}
}
}
// If the client supports a greater major version than the server,
// set the version to the highest one the server supports.
if (majorVersion > MAJOR_VERSION) {
majorVersion = MAJOR_VERSION;
minorVersion = MINOR_VERSION;
}
else if (majorVersion == MAJOR_VERSION) {
// If the client supports a greater minor version than the
// server, set the version to the highest one that the server
// supports.
if (minorVersion > MINOR_VERSION) {
minorVersion = MINOR_VERSION;
}
} }
// Store language and version information in the connection.
connection.setLanaguage(language);
connection.setXMPPVersion(majorVersion, minorVersion);
// Create a ClientSession for this user.
Session session = SessionManager.getInstance().createClientSession(connection);
Writer writer = connection.getWriter(); Writer writer = connection.getWriter();
// Build the start packet response // Build the start packet response
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
...@@ -112,18 +156,58 @@ public class ClientSession extends Session { ...@@ -112,18 +156,58 @@ public class ClientSession extends Session {
sb.append(session.getStreamID().toString()); sb.append(session.getStreamID().toString());
sb.append("\" xml:lang=\""); sb.append("\" xml:lang=\"");
sb.append(language); sb.append(language);
// Don't include version info if the version is 0.0.
if (majorVersion != 0) {
sb.append("\" version=\"");
sb.append(majorVersion).append(".").append(minorVersion);
}
sb.append("\">"); sb.append("\">");
writer.write(sb.toString()); writer.write(sb.toString());
// If this is a flash client then flag the connection and append a special caracter // If this is a "Jabber" connection, the session is now initialized and we can
// to the response // return to allow normal packet parsing.
if (majorVersion == 0) {
// If this is a flash client append a special caracter to the response.
if (isFlashClient) {
writer.write('\0');
}
writer.flush();
return session;
}
// Otherwise, this is at least XMPP 1.0 so we need to announce stream features.
sb = new StringBuilder();
sb.append("<stream:features>");
sb.append("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\">");
// sb.append("<required/>");
sb.append("</starttls></stream:features>");
writer.write(sb.toString());
if (isFlashClient) { if (isFlashClient) {
session.getConnection().setFlashClient(true);
writer.write('\0'); writer.write('\0');
} }
writer.flush(); writer.flush();
// TODO: check for SASL support in opening stream tag
boolean done = false;
while (!done) {
if (xpp.next() == XmlPullParser.START_TAG) {
done = true;
if (xpp.getName().equals("starttls") &&
xpp.getNamespace(xpp.getPrefix()).equals(TLS_NAMESPACE))
{
writer.write("<proceed xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>");
if (isFlashClient) {
writer.write('\0');
}
writer.flush();
// TODO: setup SSLEngine and negotiate TLS.
}
}
}
return session; return session;
} }
...@@ -161,11 +245,13 @@ public class ClientSession extends Session { ...@@ -161,11 +245,13 @@ public class ClientSession extends Session {
* status to authenticated and enables many features that are not * status to authenticated and enables many features that are not
* available until authenticated (obtaining managers for example). * available until authenticated (obtaining managers for example).
* *
* @param auth The authentication token obtained from the AuthFactory * @param auth the authentication token obtained from the AuthFactory.
* @param resource The resource this session authenticated under * @param resource the resource this session authenticated under.
* @param userManager The user manager this authentication occured under * @param userManager the user manager this authentication occured under.
*/ */
public void setAuthToken(AuthToken auth, UserManager userManager, String resource) throws UserNotFoundException { public void setAuthToken(AuthToken auth, UserManager userManager, String resource)
throws UserNotFoundException
{
User user = userManager.getUser(auth.getUsername()); User user = userManager.getUser(auth.getUsername());
setAddress(new JID(user.getUsername(), getServerName(), resource)); setAddress(new JID(user.getUsername(), getServerName(), resource));
authToken = auth; authToken = auth;
...@@ -186,9 +272,9 @@ public class ClientSession extends Session { ...@@ -186,9 +272,9 @@ public class ClientSession extends Session {
} }
/** /**
* <p>Obtain the authentication token associated with this session.</p> * Returns the authentication token associated with this session.
* *
* @return The authentication token associated with this session (can be null) * @return the authentication token associated with this session (can be null).
*/ */
public AuthToken getAuthToken() { public AuthToken getAuthToken() {
return authToken; return authToken;
...@@ -289,15 +375,7 @@ public class ClientSession extends Session { ...@@ -289,15 +375,7 @@ public class ClientSession extends Session {
catch (Exception e) { catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e); Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
// TODO: Should attempt to do something with the packet // TODO: Should attempt to do something with the packet
try { conn.close();
conn.close();
}
catch (UnauthorizedException e1) {
// TODO: something more intelligent, if the connection is
// already closed this will throw an exception but it is not a
// logged error
Log.error(LocaleUtils.getLocalizedString("admin.error"), e1);
}
} }
} }
} }
......
...@@ -178,7 +178,7 @@ public class ComponentSession extends Session { ...@@ -178,7 +178,7 @@ public class ComponentSession extends Session {
super(serverName, conn, id); super(serverName, conn, id);
} }
public void process(Packet packet) throws UnauthorizedException, PacketException { public void process(Packet packet) throws PacketException {
// Since ComponentSessions are not being stored in the RoutingTable this messages is very // Since ComponentSessions are not being stored in the RoutingTable this messages is very
// unlikely to be sent // unlikely to be sent
component.processPacket(packet); component.processPacket(packet);
...@@ -209,12 +209,7 @@ public class ComponentSession extends Session { ...@@ -209,12 +209,7 @@ public class ComponentSession extends Session {
} }
catch (Exception e) { catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e); Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
try { conn.close();
conn.close();
}
catch (UnauthorizedException e1) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e1);
}
} }
} }
} }
......
...@@ -11,9 +11,8 @@ ...@@ -11,9 +11,8 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
import org.dom4j.io.XMLWriter; import org.jivesoftware.messenger.auth.UnauthorizedException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
...@@ -27,136 +26,141 @@ import java.io.Writer; ...@@ -27,136 +26,141 @@ import java.io.Writer;
public interface Connection { public interface Connection {
/** /**
* <p>Verify that the connection is still live.</p> * Verifies that the connection is still live. Typically this is done by
* <p>Typically this is done by sending a whitespace character between packets.</p> * sending a whitespace character between packets.
* *
* @return True if the socket remains valid, false otherwise * @return true if the socket remains valid, false otherwise.
*/ */
boolean validate(); public boolean validate();
/** /**
* Initializes the connection with it's owning session. Allows the * Initializes the connection with it's owning session. Allows the
* connection class to configure itself with session related information * connection class to configure itself with session related information
* (e.g. stream ID). * (e.g. stream ID).
* *
* @param session The session that owns this connection * @param session the session that owns this connection
*/
void init(Session session);
/**
* <p>Obtain the InetAddress describing the connection.</p>
*
* @return The InetAddress describing the underlying connection properties
* @throws UnauthorizedException If caller doesn't have permission to
* access this resource
*/ */
InetAddress getInetAddress() throws UnauthorizedException, UnknownHostException; public void init(Session session);
/** /**
* <p>Obtain the XmlSerializer used to send data to the client.</p> * Returns the InetAddress describing the connection.
* <P>The serializer should only be used to obtain information about the
* serialization and should not be written to directly. Other threads maybe
* trying to write to the serializer so it is important that all writes are
* properly synchronized.</p>
* *
* @return The XmlSerializer underlying this connection * @return the InetAddress describing the underlying connection properties.
* @throws UnauthorizedException If caller doesn't have permission to access this resource
*/ */
XMLWriter getSerializer() throws UnauthorizedException; public InetAddress getInetAddress() throws UnknownHostException;
/** /**
* <p>Obtain the Writer used to send data to the client.</p> * Returns the Writer used to send data to the connection. The writer should be
* <P>The writer should be used with caution.</p> * used with caution. In the majority of cases, the {@link #deliver(Packet)}
* * method should be used to send data instead of using the writer directly.
* @return The Writer underlying this connection * You must synchronize on the writer before writing data to it to ensure
* @throws UnauthorizedException If caller doesn't have permission to access this resource * data consistency:
*/ *
Writer getWriter() throws UnauthorizedException; * <pre>
* Writer writer = connection.getWriter();
* synchronized(writer) {
* // write data....
* }</pre>
*
* @return the Writer for this connection.
*/
public Writer getWriter();
/** /**
* Close this session including associated socket connection. * Close this session including associated socket connection. The order of
* <p/> * events for closing the session is:
* Any selector registrations (if using nio) are also removed.
* The order of events for closing the session is:
* <ul> * <ul>
* <li>set closing flag to prevent redundant shutdowns * <li>Set closing flag to prevent redundant shutdowns.
* <li>notifyEvent all listeners that the channel is shutting down * <li>Call notifyEvent all listeners that the channel is shutting down.
* <li>close the socket * <li>Close the socket.
* </ul> * </ul>
*
* @throws UnauthorizedException If caller doesn't have permission to access this resource
*/ */
void close() throws UnauthorizedException; public void close();
/** /**
* Retrieve the closed state of the Session. * Returns true if the connection/session is closed.
* *
* @return True if the session is closed * @return true if the connection is closed.
*/ */
boolean isClosed(); public boolean isClosed();
/** /**
* <p>Determines if this connection is secure.</p> * Returns true if this connection is secure.
* *
* @return True if the connection is secure (e.g. SSL/TLS) * @return true if the connection is secure (e.g. SSL/TLS)
*/ */
boolean isSecure(); public boolean isSecure();
/** /**
* Register a listener for close event notification. Registrations after * Registers a listener for close event notification. Registrations after
* the Session is closed will be immediately notified <em>before</em> * the Session is closed will be immediately notified <em>before</em>
* the registration call returns (within the context of the * the registration call returns (within the context of the
* registration call). An optional handback object can be associated with * registration call). An optional handback object can be associated with
* the registration if the same listener is registered to listen for multiple * the registration if the same listener is registered to listen for multiple
* connection closures. * connection closures.
* *
* @param listener The listener to register for events * @param listener the listener to register for events.
* @param handbackMessage The object to send in the event notification * @param handbackMessage the object to send in the event notification.
* @return The message previously registered for this channel or null if no registration existed * @return the message previously registered for this channel or <tt>null</tt>
* @throws UnauthorizedException If caller doesn't have permission to access this resource * if no registration existed
*/ */
Object registerCloseListener(ConnectionCloseListener listener, Object handbackMessage) throws UnauthorizedException; public Object registerCloseListener(ConnectionCloseListener listener, Object handbackMessage);
/** /**
* 9 * Removes a registered close event listener. Registered listeners must
* Remove a registered close event listener. Registered listeners must
* be able to receive close events up until the time this method returns. * be able to receive close events up until the time this method returns.
* (i.e. It is possible to call unregister, receive a close event registration, * (i.e. it is possible to call unregister, receive a close event registration,
* and then have the unregister call return.) * and then have the unregister call return.)
* *
* @param listener The listener to deregister for close events * @param listener the listener to deregister for close events.
* @return The Message registered with this listener or null if the channel was never registered * @return the Message registered with this listener or <tt>null</tt> if the
* @throws UnauthorizedException If caller doesn't have permission to access this resource * channel was never registered.
*/ */
Object removeCloseListener(ConnectionCloseListener listener) throws UnauthorizedException; public Object removeCloseListener(ConnectionCloseListener listener);
/** /**
* Delivers the packet to this XMPPAddress without checking the recipient. * Delivers the packet to this connection without checking the recipient.
* The method essentially calls * The method essentially calls <code>socket.send(packet.getWriteBuffer())</code>.
* <code>socket.send(packet.getWriteBuffer())</code>
* *
* @param packet The packet to deliver. * @param packet the packet to deliver.
* @throws UnauthorizedException If caller doesn't have permission to access this resource
*/ */
void deliver(Packet packet) throws UnauthorizedException; public void deliver(Packet packet) throws UnauthorizedException;
/** /**
* Sets whether the connected client is a flash client or not. Flash clients need to receive * Returns true if the connected client is a flash client. Flash clients need
* a special character (i.e. \0) at the end of each xml packet. Flash clients may send the * to receive a special character (i.e. \0) at the end of each xml packet. Flash
* character \0 in incoming packets and may start a connection using another openning tag * clients may send the character \0 in incoming packets and may start a connection
* such as: "flash:client". * using another openning tag such as: "flash:client".
* *
* @param flashClient flag that indicates if the client is a flash client. * @return true if the connected client is a flash client.
*/ */
void setFlashClient(boolean flashClient); public boolean isFlashClient();
/** /**
* Returns true if the connected client is a flash client. Flash clients need to receive * Returns the major version of XMPP being used by this connection
* a special character (i.e. \0) at the end of each xml packet. Flash clients may send the * (major_version.minor_version. In most cases, the version should be
* character \0 in incoming packets and may start a connection using another openning tag * "1.0". However, older clients using the "Jabber" protocol do not set a
* such as: "flash:client". * version. In that case, the version is "0.0".
* *
* @return true if the connected client is a flash client. * @return the major XMPP version being used by this connection.
*/
public int getMajorXMPPVersion();
/**
* Returns the minor version of XMPP being used by this connection
* (major_version.minor_version. In most cases, the version should be
* "1.0". However, older clients using the "Jabber" protocol do not set a
* version. In that case, the version is "0.0".
*
* @return the minor XMPP version being used by this connection.
*/
public int getMinorXMPPVersion();
/**
* Returns the language code that should be used for this connection
* (e.g. "en").
*
* @return the language code for the connection.
*/ */
boolean isFlashClient(); public String getLanguage();
} }
...@@ -16,23 +16,25 @@ import java.util.Iterator; ...@@ -16,23 +16,25 @@ import java.util.Iterator;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
/** /**
* <p>Coordinates connections (accept, read, termination) on the server.</p> * Coordinates connections (accept, read, termination) on the server.
* *
* @author Iain Shigeoka * @author Iain Shigeoka
*/ */
public interface ConnectionManager { public interface ConnectionManager {
/** /**
* <p>Obtain an array of the ports managed by this connection manager.</p> * Returns an array of the ports managed by this connection manager.
* *
* @return Iterator of the ports managed by this connection manager (can be an empty but never null) * @return an iterator of the ports managed by this connection manager
* (can be an empty but never null).
*/ */
public Iterator<ServerPort> getPorts(); public Iterator<ServerPort> getPorts();
/** /**
* <p>Adds a socket to be managed by the connection manager.</p> * Adds a socket to be managed by the connection manager.
* *
* @param sock The socket to add to this manager for management * @param socket the socket to add to this manager for management.
* @param isSecure True if this is a secure connection * @param isSecure true if the connection is secure.
*/ */
public void addSocket(Socket sock, boolean isSecure) throws XmlPullParserException; public void addSocket(Socket socket, boolean isSecure) throws XmlPullParserException;
} }
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.dom4j.Element; import org.dom4j.Element;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.container.BasicModule; import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.messenger.handler.IQHandler; import org.jivesoftware.messenger.handler.IQHandler;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
...@@ -215,33 +214,23 @@ public class IQRouter extends BasicModule { ...@@ -215,33 +214,23 @@ public class IQRouter extends BasicModule {
Log.info("Packet sent to unreachable address " + packet); Log.info("Packet sent to unreachable address " + packet);
Session session = sessionManager.getSession(packet.getFrom()); Session session = sessionManager.getSession(packet.getFrom());
if (session != null) { if (session != null) {
try { IQ reply = IQ.createResultIQ(packet);
IQ reply = IQ.createResultIQ(packet); reply.setChildElement(packet.getChildElement().createCopy());
reply.setChildElement(packet.getChildElement().createCopy()); reply.setError(PacketError.Condition.service_unavailable);
reply.setError(PacketError.Condition.service_unavailable); session.getConnection().deliver(reply);
session.getConnection().deliver(reply);
}
catch (UnauthorizedException ex) {
Log.error(LocaleUtils.getLocalizedString("admin.error.routing"), e);
}
} }
} }
} }
} }
catch (Exception e) { catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error.routing"), e); Log.error(LocaleUtils.getLocalizedString("admin.error.routing"), e);
try { Session session = sessionManager.getSession(packet.getFrom());
Session session = sessionManager.getSession(packet.getFrom()); if (session != null) {
if (session != null) { Connection conn = session.getConnection();
Connection conn = session.getConnection(); if (conn != null) {
if (conn != null) { conn.close();
conn.close();
}
} }
} }
catch (UnauthorizedException e1) {
// do nothing
}
} }
} }
......
...@@ -255,7 +255,7 @@ public class InternalComponentManager implements ComponentManager, RoutableChann ...@@ -255,7 +255,7 @@ public class InternalComponentManager implements ComponentManager, RoutableChann
* *
* @param packet the packet to process. * @param packet the packet to process.
*/ */
public void process(Packet packet) throws UnauthorizedException, PacketException { public void process(Packet packet) throws PacketException {
Component component = getComponent(packet.getFrom().getDomain()); Component component = getComponent(packet.getFrom().getDomain());
// Only process packets that were sent by registered components // Only process packets that were sent by registered components
if (component != null) { if (component != null) {
...@@ -293,7 +293,7 @@ public class InternalComponentManager implements ComponentManager, RoutableChann ...@@ -293,7 +293,7 @@ public class InternalComponentManager implements ComponentManager, RoutableChann
return jid; return jid;
} }
public void process(Packet packet) throws UnauthorizedException, PacketException { public void process(Packet packet) throws PacketException {
component.processPacket(packet); component.processPacket(packet);
} }
} }
......
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
import org.jivesoftware.messenger.auth.UnauthorizedException;
/** /**
* Delivers packets to locally connected streams. This is the opposite * Delivers packets to locally connected streams. This is the opposite
...@@ -29,8 +29,8 @@ public interface PacketDeliverer { ...@@ -29,8 +29,8 @@ public interface PacketDeliverer {
* Be careful to enforce concurrency DbC of concurrent by synchronizing * Be careful to enforce concurrency DbC of concurrent by synchronizing
* any accesses to class resources. * any accesses to class resources.
* *
* @param packet The packet to route * @param packet the packet to route
* @throws java.lang.NullPointerException If the packet is null or the packet could not be routed * @throws PacketException if the packet is null or the packet could not be routed.
*/ */
public void deliver(Packet packet) throws UnauthorizedException, PacketException; public void deliver(Packet packet) throws UnauthorizedException, PacketException;
} }
...@@ -112,18 +112,13 @@ public class PresenceRouter extends BasicModule { ...@@ -112,18 +112,13 @@ public class PresenceRouter extends BasicModule {
} }
catch (Exception e) { catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error.routing"), e); Log.error(LocaleUtils.getLocalizedString("admin.error.routing"), e);
try { Session session = sessionManager.getSession(packet.getFrom());
Session session = sessionManager.getSession(packet.getFrom()); if (session != null) {
if (session != null) { Connection conn = session.getConnection();
Connection conn = session.getConnection(); if (conn != null) {
if (conn != null) { conn.close();
conn.close();
}
} }
} }
catch (UnauthorizedException e1) {
// do nothing
}
} }
} }
......
...@@ -36,8 +36,8 @@ public interface DiscoItemsProvider { ...@@ -36,8 +36,8 @@ public interface DiscoItemsProvider {
* case that the sender of the disco request is not authorized to discover items an * case that the sender of the disco request is not authorized to discover items an
* UnauthorizedException will be thrown. * UnauthorizedException will be thrown.
* *
* @param name the recipient JID's name. * @param name the recipient JID's name.
* @param node the requested disco node. * @param node the requested disco node.
* @param senderJID the XMPPAddress of user that sent the disco items request. * @param senderJID the XMPPAddress of user that sent the disco items request.
* @return an Iterator (of Element) with the target entity's items or null if none. * @return an Iterator (of Element) with the target entity's items or null if none.
* @throws UnauthorizedException if the senderJID is not authorized to discover items. * @throws UnauthorizedException if the senderJID is not authorized to discover items.
......
...@@ -246,5 +246,4 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv ...@@ -246,5 +246,4 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
}; };
return discoItemsProvider; return discoItemsProvider;
} }
}
} \ No newline at end of file
...@@ -42,7 +42,7 @@ public abstract class IQHandler extends BasicModule implements ChannelHandler { ...@@ -42,7 +42,7 @@ public abstract class IQHandler extends BasicModule implements ChannelHandler {
super(moduleName); super(moduleName);
} }
public void process(Packet packet) throws UnauthorizedException, PacketException { public void process(Packet packet) throws PacketException {
IQ iq = (IQ) packet; IQ iq = (IQ) packet;
try { try {
iq = handleIQ(iq); iq = handleIQ(iq);
......
...@@ -18,7 +18,6 @@ import org.jivesoftware.util.Log; ...@@ -18,7 +18,6 @@ import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.*; import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.roster.Roster; import org.jivesoftware.messenger.roster.Roster;
import org.jivesoftware.messenger.roster.RosterItem; import org.jivesoftware.messenger.roster.RosterItem;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.*; import org.jivesoftware.messenger.user.*;
import org.xmpp.packet.Presence; import org.xmpp.packet.Presence;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
...@@ -82,7 +81,7 @@ public class PresenceSubscribeHandler extends BasicModule implements ChannelHand ...@@ -82,7 +81,7 @@ public class PresenceSubscribeHandler extends BasicModule implements ChannelHand
super("Presence subscription handler"); super("Presence subscription handler");
} }
public void process(Packet xmppPacket) throws UnauthorizedException, PacketException { public void process(Packet xmppPacket) throws PacketException {
Presence presence = (Presence)xmppPacket; Presence presence = (Presence)xmppPacket;
try { try {
JID senderJID = presence.getFrom(); JID senderJID = presence.getFrom();
......
...@@ -62,21 +62,14 @@ public class SSLSocketAcceptThread extends Thread { ...@@ -62,21 +62,14 @@ public class SSLSocketAcceptThread extends Thread {
* Creates an instance using the default port, TLS transport security, and * Creates an instance using the default port, TLS transport security, and
* JVM defaults for all security settings. * JVM defaults for all security settings.
* *
* @param connManager The connection manager that will manage connections generated by this thread * @param connManager the connection manager that will manage connections
* @throws IOException If there was trouble initializing the SSL configuration * generated by this thread
* @throws IOException if there was trouble initializing the SSL configuration.
*/ */
public SSLSocketAcceptThread(ConnectionManager connManager) public SSLSocketAcceptThread(ConnectionManager connManager) throws IOException {
throws IOException { super("Secure Socket Listener");
super("SSL accept");
this.connManager = connManager; this.connManager = connManager;
int port = SSLSocketAcceptThread.DEFAULT_PORT; int port = JiveGlobals.getIntProperty("xmpp.socket.ssl.port", DEFAULT_PORT);
String portName = JiveGlobals.getProperty("xmpp.socket.ssl.port");
if (portName != null) {
int portValue = Integer.parseInt(portName);
if (portValue > 0) {
port = Integer.parseInt(portName);
}
}
String interfaceName = JiveGlobals.getProperty("xmpp.socket.ssl.interface"); String interfaceName = JiveGlobals.getProperty("xmpp.socket.ssl.interface");
bindInterface = null; bindInterface = null;
......
...@@ -57,7 +57,7 @@ public class SocketAcceptThread extends Thread { ...@@ -57,7 +57,7 @@ public class SocketAcceptThread extends Thread {
private ConnectionManager connManager; private ConnectionManager connManager;
public SocketAcceptThread(ConnectionManager connManager) { public SocketAcceptThread(ConnectionManager connManager) {
super("SAT accept"); super("Socket Listener");
this.connManager = connManager; this.connManager = connManager;
port = JiveGlobals.getIntProperty("xmpp.socket.plain.port", DEFAULT_PORT); port = JiveGlobals.getIntProperty("xmpp.socket.plain.port", DEFAULT_PORT);
String interfaceName = JiveGlobals.getProperty("xmpp.socket.plain.interface"); String interfaceName = JiveGlobals.getProperty("xmpp.socket.plain.interface");
......
...@@ -12,13 +12,10 @@ ...@@ -12,13 +12,10 @@
package org.jivesoftware.messenger.net; package org.jivesoftware.messenger.net;
import org.dom4j.io.XMLWriter; import org.dom4j.io.XMLWriter;
import org.jivesoftware.messenger.PacketDeliverer; import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.PacketException;
import org.jivesoftware.messenger.Session;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.interceptor.InterceptorManager; import org.jivesoftware.messenger.interceptor.InterceptorManager;
import org.jivesoftware.messenger.interceptor.PacketRejectedException; import org.jivesoftware.messenger.interceptor.PacketRejectedException;
import org.jivesoftware.messenger.spi.BasicConnection;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
...@@ -29,48 +26,47 @@ import java.io.OutputStreamWriter; ...@@ -29,48 +26,47 @@ import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
/** /**
* An object to track the state of a Jabber client-server session. * An object to track the state of a XMPP client-server session.
* Currently this class contains the socket channel connecting the * Currently this class contains the socket channel connecting the
* client and server. * client and server.
* *
* @author Iain Shigeoka * @author Iain Shigeoka
*/ */
public class SocketConnection extends BasicConnection { public class SocketConnection implements Connection {
/** private Map listeners = new HashMap();
* The socket this session represents
*/ private Socket socket;
private Socket sock;
/** /**
* The utf-8 charset for decoding and encoding Jabber packet streams. * The utf-8 charset for decoding and encoding XMPP packet streams.
*/ */
private String charset = "UTF-8"; private String charset = "UTF-8";
/**
* The writer used to send outgoing data.
*/
private Writer writer; private Writer writer;
/**
* The packet deliverer for local packets
*/
private PacketDeliverer deliverer; private PacketDeliverer deliverer;
private Session session; private Session session;
private boolean secure; private boolean secure;
private XMLWriter xmlSerializer; private XMLWriter xmlSerializer;
private boolean flashClient = false; private boolean flashClient = false;
private int majorVersion = 1;
private int minorVersion = 0;
private String language = null;
/** /**
* Create a new session using the supplied socket. * Create a new session using the supplied socket.
* *
* @param deliverer The packet deliverer this connection will use * @param deliverer the packet deliverer this connection will use.
* @param socket The socket to represent * @param socket the socket to represent.
* @param isSecure True if this is a secure connection * @param isSecure true if this is a secure connection.
* @throws NullPointerException If the socket is null * @throws NullPointerException if the socket is null.
*/ */
public SocketConnection(PacketDeliverer deliverer, Socket socket, boolean isSecure) public SocketConnection(PacketDeliverer deliverer, Socket socket, boolean isSecure)
throws IOException throws IOException
...@@ -80,8 +76,8 @@ public class SocketConnection extends BasicConnection { ...@@ -80,8 +76,8 @@ public class SocketConnection extends BasicConnection {
} }
this.secure = isSecure; this.secure = isSecure;
sock = socket; this.socket = socket;
writer = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream(), charset)); writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), charset));
this.deliverer = deliverer; this.deliverer = deliverer;
xmlSerializer = new XMLWriter(writer); xmlSerializer = new XMLWriter(writer);
} }
...@@ -107,26 +103,32 @@ public class SocketConnection extends BasicConnection { ...@@ -107,26 +103,32 @@ public class SocketConnection extends BasicConnection {
session = owner; session = owner;
} }
public InetAddress getInetAddress() throws UnauthorizedException { public Object registerCloseListener(ConnectionCloseListener listener, Object handbackMessage) {
return sock.getInetAddress(); Object status = null;
if (isClosed()) {
listener.onConnectionClose(handbackMessage);
}
else {
status = listeners.put(listener, handbackMessage);
}
return status;
} }
public XMLWriter getSerializer() throws UnauthorizedException { public Object removeCloseListener(ConnectionCloseListener listener) {
return xmlSerializer; return listeners.remove(listener);
} }
public Writer getWriter() throws UnauthorizedException { public InetAddress getInetAddress() {
return socket.getInetAddress();
}
public Writer getWriter() {
return writer; return writer;
} }
/**
* Retrieve the closed state of the Session.
*
* @return true if the session is closed.
*/
public boolean isClosed() { public boolean isClosed() {
if (session == null) { if (session == null) {
return sock.isClosed(); return socket.isClosed();
} }
return session.getStatus() == Session.STATUS_CLOSED; return session.getStatus() == Session.STATUS_CLOSED;
} }
...@@ -135,6 +137,56 @@ public class SocketConnection extends BasicConnection { ...@@ -135,6 +137,56 @@ public class SocketConnection extends BasicConnection {
return secure; return secure;
} }
public int getMajorXMPPVersion() {
return majorVersion;
}
public int getMinorXMPPVersion() {
return minorVersion;
}
/**
* Sets the XMPP version information. In most cases, the version should be "1.0".
* However, older clients using the "Jabber" protocol do not set a version. In that
* case, the version is "0.0".
*
* @param majorVersion the major version.
* @param minorVersion the minor version.
*/
public void setXMPPVersion(int majorVersion, int minorVersion) {
this.majorVersion = majorVersion;
this.minorVersion = minorVersion;
}
public String getLanguage() {
return language;
}
/**
* Sets the language code that should be used for this connection (e.g. "en").
*
* @param language the language code.
*/
public void setLanaguage(String language) {
this.language = language;
}
public boolean isFlashClient() {
return flashClient;
}
/**
* Sets whether the connected client is a flash client. Flash clients need to
* receive a special character (i.e. \0) at the end of each xml packet. Flash
* clients may send the character \0 in incoming packets and may start a
* connection using another openning tag such as: "flash:client".
*
* @param flashClient true if the if the connection is a flash client.
*/
public void setFlashClient(boolean flashClient) {
this.flashClient = flashClient;
}
public synchronized void close() { public synchronized void close() {
if (!isClosed()) { if (!isClosed()) {
try { try {
...@@ -156,7 +208,7 @@ public class SocketConnection extends BasicConnection { ...@@ -156,7 +208,7 @@ public class SocketConnection extends BasicConnection {
// Do nothing // Do nothing
} }
try { try {
sock.close(); socket.close();
} }
catch (Exception e) { catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error.close") Log.error(LocaleUtils.getLocalizedString("admin.error.close")
...@@ -166,12 +218,6 @@ public class SocketConnection extends BasicConnection { ...@@ -166,12 +218,6 @@ public class SocketConnection extends BasicConnection {
} }
} }
/**
* Delivers the packet to this XMPPAddress without checking the recipient.
* The method essentially calls <tt>packet.send(serializer,version)</tt>.
*
* @param packet The packet to deliver.
*/
public void deliver(Packet packet) throws UnauthorizedException, PacketException { public void deliver(Packet packet) throws UnauthorizedException, PacketException {
if (isClosed()) { if (isClosed()) {
deliverer.deliver(packet); deliverer.deliver(packet);
...@@ -203,11 +249,17 @@ public class SocketConnection extends BasicConnection { ...@@ -203,11 +249,17 @@ public class SocketConnection extends BasicConnection {
} }
} }
public void setFlashClient(boolean flashClient) { /**
this.flashClient = flashClient; * Notifies all close listeners that the connection has been closed.
} * Used by subclasses to properly finish closing the connection.
*/
public boolean isFlashClient() { private void notifyCloseListeners() {
return flashClient; synchronized (listeners) {
Iterator itr = listeners.keySet().iterator();
while (itr.hasNext()) {
ConnectionCloseListener listener = (ConnectionCloseListener)itr.next();
listener.onConnectionClose(listeners.get(listener));
}
}
} }
} }
\ No newline at end of file
...@@ -47,9 +47,9 @@ public class SocketReadThread extends Thread { ...@@ -47,9 +47,9 @@ public class SocketReadThread extends Thread {
*/ */
private static XmlPullParserFactory factory = null; private static XmlPullParserFactory factory = null;
private Socket sock; private Socket socket;
private Session session; private Session session;
private Connection connection; private SocketConnection connection;
private String serverName; private String serverName;
/** /**
* Router used to route incoming packets to the correct channels. * Router used to route incoming packets to the correct channels.
...@@ -67,21 +67,22 @@ public class SocketReadThread extends Thread { ...@@ -67,21 +67,22 @@ public class SocketReadThread extends Thread {
} }
} }
/** /**
* Create dedicated read thread for this socket. * Creates a dedicated read thread for a socket.
* *
* @param router The router for sending packets that were read * @param router the router for sending packets that were read.
* @param serverName The name of the server this socket is working for * @param serverName the name of the server this socket is working for.
* @param sock The socket to read from * @param socket the socket to read from.
* @param conn The connection being read * @param connection the connection being read.
*/ */
public SocketReadThread(PacketRouter router, String serverName, Socket sock, Connection conn) { public SocketReadThread(PacketRouter router, String serverName, Socket socket,
SocketConnection connection)
{
super("SRT reader"); super("SRT reader");
this.serverName = serverName; this.serverName = serverName;
this.router = router; this.router = router;
this.connection = conn; this.connection = connection;
this.sock = sock; this.socket = socket;
} }
/** /**
...@@ -93,7 +94,7 @@ public class SocketReadThread extends Thread { ...@@ -93,7 +94,7 @@ public class SocketReadThread extends Thread {
reader = new XPPPacketReader(); reader = new XPPPacketReader();
reader.setXPPFactory(factory); reader.setXPPFactory(factory);
reader.getXPPParser().setInput(new InputStreamReader(sock.getInputStream(), reader.getXPPParser().setInput(new InputStreamReader(socket.getInputStream(),
CHARSET)); CHARSET));
// Read in the opening tag and prepare for packet stream // Read in the opening tag and prepare for packet stream
...@@ -109,8 +110,8 @@ public class SocketReadThread extends Thread { ...@@ -109,8 +110,8 @@ public class SocketReadThread extends Thread {
// Normal disconnect // Normal disconnect
} }
catch (SocketException se) { catch (SocketException se) {
// The socket was closed. The server may close the connection for several reasons (e.g. // The socket was closed. The server may close the connection for several
// user requested to remove his account). Do nothing here. // reasons (e.g. user requested to remove his account). Do nothing here.
} }
catch (XmlPullParserException ie) { catch (XmlPullParserException ie) {
// Check if the user abruptly cut the connection without sending previously an // Check if the user abruptly cut the connection without sending previously an
...@@ -131,9 +132,9 @@ public class SocketReadThread extends Thread { ...@@ -131,9 +132,9 @@ public class SocketReadThread extends Thread {
} }
} }
// It is normal for clients to abruptly cut a connection // It is normal for clients to abruptly cut a connection
// rather than closing the stream document // rather than closing the stream document. Since this is
// Since this is normal behavior, we won't log it as an error // normal behavior, we won't log it as an error.
// Log.error(LocaleUtils.getLocalizedString("admin.disconnect"),ie); // Log.error(LocaleUtils.getLocalizedString("admin.disconnect"),ie);
} }
catch (Exception e) { catch (Exception e) {
if (session != null) { if (session != null) {
...@@ -152,31 +153,26 @@ public class SocketReadThread extends Thread { ...@@ -152,31 +153,26 @@ public class SocketReadThread extends Thread {
} }
catch (Exception e) { catch (Exception e) {
Log.warn(LocaleUtils.getLocalizedString("admin.error.connection") Log.warn(LocaleUtils.getLocalizedString("admin.error.connection")
+ "\n" + sock.toString()); + "\n" + socket.toString());
} }
} }
else { else {
Log.error(LocaleUtils.getLocalizedString("admin.error.connection") Log.error(LocaleUtils.getLocalizedString("admin.error.connection")
+ "\n" + sock.toString()); + "\n" + socket.toString());
} }
} }
} }
/** /**
* Read the incoming stream until it ends. Much of the reading * Read the incoming stream until it ends.
* will actually be done in the channel handlers as they run the
* XPP through the data. This method mostly handles the idle waiting
* for incoming data. To prevent clients from stalling channel handlers,
* a watch dog timer is used. Packets that take longer than the watch
* dog limit to read will cause the session to be closed.
*/ */
private void readStream() throws Exception { private void readStream() throws Exception {
while (true) { while (true) {
Element doc = reader.parseDocument().getRootElement(); Element doc = reader.parseDocument().getRootElement();
if (doc == null) { if (doc == null) {
// Stop reading the stream since the client has sent an end of stream element and // Stop reading the stream since the client has sent an end of
// probably closed the connection // stream element and probably closed the connection.
return; return;
} }
...@@ -187,7 +183,7 @@ public class SocketReadThread extends Thread { ...@@ -187,7 +183,7 @@ public class SocketReadThread extends Thread {
packet = new Message(doc); packet = new Message(doc);
} }
catch(IllegalArgumentException e) { catch(IllegalArgumentException e) {
// The original packet contains a malformed JID so answer an error // The original packet contains a malformed JID so answer with an error.
Message reply = new Message(); Message reply = new Message();
reply.setID(doc.attributeValue("id")); reply.setID(doc.attributeValue("id"));
reply.setTo(session.getAddress()); reply.setTo(session.getAddress());
...@@ -298,7 +294,8 @@ public class SocketReadThread extends Thread { ...@@ -298,7 +294,8 @@ public class SocketReadThread extends Thread {
} }
} }
else { else {
throw new XmlPullParserException(LocaleUtils.getLocalizedString("admin.error.packet.tag") + tag); throw new XmlPullParserException(LocaleUtils.getLocalizedString(
"admin.error.packet.tag") + tag);
} }
} }
} }
......
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.spi;
import org.jivesoftware.messenger.Connection;
import org.jivesoftware.messenger.ConnectionCloseListener;
import org.jivesoftware.messenger.Session;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Connection helper base class. Automates common connection management
* tasks without specific knowledge of the underlying connection provider.
*
* @author Iain Shigeoka
*/
abstract public class BasicConnection implements Connection {
private Map listeners = new HashMap();
public void init(Session session) {
}
public Object registerCloseListener(ConnectionCloseListener listener, Object handbackMessage) {
Object status = null;
if (isClosed()) {
listener.onConnectionClose(handbackMessage);
}
else {
status = listeners.put(listener, handbackMessage);
}
return status;
}
public Object removeCloseListener(ConnectionCloseListener listener) {
return listeners.remove(listener);
}
/**
* Notifies all close listeners that the connection has been closed.
* Used by subclasses to properly finish closing the connection.
*/
protected void notifyCloseListeners() {
synchronized (listeners) {
Iterator itr = listeners.keySet().iterator();
while (itr.hasNext()) {
ConnectionCloseListener listener = (ConnectionCloseListener)itr.next();
listener.onConnectionClose(listeners.get(listener));
}
}
}
}
...@@ -107,7 +107,7 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana ...@@ -107,7 +107,7 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
public void addSocket(Socket sock, boolean isSecure) { public void addSocket(Socket sock, boolean isSecure) {
try { try {
// the order of these calls is critical (stupid huh?) // the order of these calls is critical (stupid huh?)
Connection conn = new SocketConnection(deliverer, sock, isSecure); SocketConnection conn = new SocketConnection(deliverer, sock, isSecure);
SocketReadThread reader = new SocketReadThread(router, serverName, sock, conn); SocketReadThread reader = new SocketReadThread(router, serverName, sock, conn);
reader.setDaemon(true); reader.setDaemon(true);
reader.start(); reader.start();
......
...@@ -60,9 +60,6 @@ public class TransportHandler extends BasicModule implements ChannelHandler { ...@@ -60,9 +60,6 @@ public class TransportHandler extends BasicModule implements ChannelHandler {
try { try {
deliverer.deliver(packet); deliverer.deliver(packet);
} }
catch (UnauthorizedException e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
catch (PacketException e) { catch (PacketException e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e); Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment