Added status for the registration events. Status when login failer occurs, status on discconect - multiple logins. Fixed instantly detection of disconnect with reason multiple logins.

cusax-fix
Damian Minkov 20 years ago
parent 5717f4adf6
commit c028fc0b69

@ -16,6 +16,12 @@
import net.java.sip.communicator.util.*;
import net.kano.joustsim.oscar.oscar.loginstatus.*;
import net.java.sip.communicator.impl.protocol.icq.message.DefaultCmdFactory;
import net.kano.joscar.flap.FlapCommand;
import net.kano.joscar.flap.FlapPacketListener;
import net.kano.joscar.flap.FlapPacketEvent;
import net.kano.joscar.flapcmd.CloseFlapCmd;
import net.kano.joscar.snaccmd.auth.AuthResponse;
import net.kano.joustsim.oscar.oscar.service.Service;
/**
* An implementation of the protocol provider service over the AIM/ICQ protocol
@ -368,6 +374,22 @@ private void fireRegistrationStateChanged( State oldJoustSimState,
= joustSimStateToRegistrationState(newJoustSimState
, newJoustSimStateInfo);
if(newJoustSimStateInfo instanceof LoginFailureStateInfo)
{
LoginFailureInfo loginFailer =
((LoginFailureStateInfo)newJoustSimStateInfo).getLoginFailureInfo();
if(loginFailer instanceof AuthFailureInfo)
{
int code = ConnectionClosedListener.
convertAuthCodeToReasonCode((AuthFailureInfo)loginFailer);
reasonCode = ConnectionClosedListener.
convertCodeToRegistrationStateChangeEvent(code);
reason = ConnectionClosedListener.convertCodeToStringReason(code);
}
}
fireRegistrationStateChanged(oldRegistrationState, newRegistrationState
, reasonCode, reason);
@ -425,6 +447,9 @@ public void handleStateChange(StateEvent event)
+ " changed registration status from "
+ oldState + " to " + newState);
int reasonCode = RegistrationStateChangeEvent.REASON_NOT_SPECIFIED;
String reasonStr = null;
if (newState == State.ONLINE)
{
icbmService = conn.getIcbmService();
@ -436,17 +461,37 @@ public void handleStateChange(StateEvent event)
getOscarConnection().getSnacProcessor().
getCmdFactoryMgr().getDefaultFactoryList().
registerAll(new DefaultCmdFactory());
conn.getInfoService().
getOscarConnection().getSnacProcessor().
getFlapProcessor().addPacketListener(new ConnectionClosedListener(conn));
}
else if (newState == State.DISCONNECTED
|| newState == State.FAILED)
else if (newState == State.DISCONNECTED)
{
logger.debug("The aim Connection was disconnected!");
// we need a Service here. no metter which
// I've choose BosService
// we just need the oscar conenction from the service
Service service = aimConnection.getBosService();
if(service != null)
{
int discconectCode = service.getOscarConnection().getLastCloseCode();
reasonCode = ConnectionClosedListener.convertCodeToRegistrationStateChangeEvent(discconectCode);
reasonStr = ConnectionClosedListener.convertCodeToStringReason(discconectCode);
logger.debug("The aim Connection was disconnected! with reason : " + reasonStr);
}
else
logger.debug("The aim Connection was disconnected!");
}
else
if(newState == State.FAILED)
{
logger.debug("The aim Connection failed! " + event.getNewStateInfo());
}
//now tell all interested parties about what happened.
fireRegistrationStateChanged(oldState, event.getOldStateInfo()
, newState, event.getNewStateInfo()
, RegistrationStateChangeEvent.REASON_NOT_SPECIFIED, null);
, reasonCode, reasonStr);
}
}
@ -540,4 +585,149 @@ public void gotMessage(Conversation c, MessageInfo minfo)
}
/**
* Fixture for late close conenction due to
* multiple logins.
* Listening for incoming packets for the close command
* when this is received we discconect the session to force it
* because otherwise is wait for timeout of reading from the socket stream
* which leads to from 10 to 20 seconds delay of closing the session
* and connection
* */
public static class ConnectionClosedListener
implements FlapPacketListener
{
AimConnection aimConnection = null;
private final static int REASON_MULTIPLE_LOGINS = 0x0001;
private final static int REASON_BAD_PASSWORD_A = 0x0004;
private final static int REASON_BAD_PASSWORD_B = 0x0005;
private final static int REASON_NON_EXISTING_ICQ_UIN_A = 0x0007;
private final static int REASON_NON_EXISTING_ICQ_UIN_B = 0x0008;
private final static int REASON_MANY_CLIENTS_FROM_SAME_IP_A = 0x0015;
private final static int REASON_MANY_CLIENTS_FROM_SAME_IP_B = 0x0016;
private final static int REASON_CONNECTION_RATE_EXCEEDED = 0x0018;
private final static int REASON_CONNECTION_TOO_FAST = 0x001D;
private final static int REASON_TRY_AGAIN = 0x001E;
private final static String REASON_STRING_MULTIPLE_LOGINS = "multiple logins (on same UIN)";
private final static String REASON_STRING_BAD_PASSWORD = "bad password";
private final static String REASON_STRING_NON_EXISTING_ICQ_UIN = "non-existant UIN";
private final static String REASON_STRING_MANY_CLIENTS_FROM_SAME_IP = "too many clients from same IP";
private final static String REASON_STRING_CONNECTION_RATE_EXCEEDED = "Rate exceeded. The server temporarily bans you.";
private final static String REASON_STRING_CONNECTION_TOO_FAST = "You are reconnecting too fast";
private final static String REASON_STRING_TRY_AGAIN = "Can't register on ICQ network, try again soon.";
private final static String REASON_STRING_NOT_SPECIFIED = "Not Specified";
ConnectionClosedListener(AimConnection aimConnection)
{
this.aimConnection = aimConnection;
}
public void handleFlapPacket(FlapPacketEvent e)
{
FlapCommand flapCommand = e.getFlapCommand();
if (flapCommand instanceof CloseFlapCmd)
{
CloseFlapCmd closeCmd = (CloseFlapCmd)flapCommand;
logger.debug("received close command with code : " + closeCmd.getCode());
aimConnection.disconnect();
}
}
/**
* Converts the codes in the close command
* or the lastCloseCode of OscarConnection to the states
* which are registered in the service protocol events
*/
static int convertCodeToRegistrationStateChangeEvent(int reasonCode)
{
switch(reasonCode)
{
case REASON_MULTIPLE_LOGINS :
return RegistrationStateChangeEvent.REASON_MULTIPLE_LOGINS;
case REASON_BAD_PASSWORD_A :
return RegistrationStateChangeEvent.REASON_AUTHENTICATION_FAILED;
case REASON_BAD_PASSWORD_B :
return RegistrationStateChangeEvent.REASON_AUTHENTICATION_FAILED;
case REASON_NON_EXISTING_ICQ_UIN_A :
return RegistrationStateChangeEvent.REASON_NON_EXISTING_USER_ID;
case REASON_NON_EXISTING_ICQ_UIN_B :
return RegistrationStateChangeEvent.REASON_NON_EXISTING_USER_ID;
case REASON_MANY_CLIENTS_FROM_SAME_IP_A :
return RegistrationStateChangeEvent.REASON_CLIENT_LIMIT_REACHED_FOR_IP;
case REASON_MANY_CLIENTS_FROM_SAME_IP_B :
return RegistrationStateChangeEvent.REASON_CLIENT_LIMIT_REACHED_FOR_IP;
case REASON_CONNECTION_RATE_EXCEEDED :
return RegistrationStateChangeEvent.REASON_RECONNECTION_RATE_LIMIT_EXCEEDED;
case REASON_CONNECTION_TOO_FAST :
return RegistrationStateChangeEvent.REASON_RECONNECTION_RATE_LIMIT_EXCEEDED;
case REASON_TRY_AGAIN :
return RegistrationStateChangeEvent.REASON_RECONNECTION_RATE_LIMIT_EXCEEDED;
default :
return RegistrationStateChangeEvent.REASON_NOT_SPECIFIED;
}
}
/**
* returns the reason string corresponding to the code
* in the close command
*/
static String convertCodeToStringReason(int reasonCode)
{
switch(reasonCode)
{
case REASON_MULTIPLE_LOGINS :
return REASON_STRING_MULTIPLE_LOGINS;
case REASON_BAD_PASSWORD_A :
return REASON_STRING_BAD_PASSWORD;
case REASON_BAD_PASSWORD_B :
return REASON_STRING_BAD_PASSWORD;
case REASON_NON_EXISTING_ICQ_UIN_A :
return REASON_STRING_NON_EXISTING_ICQ_UIN;
case REASON_NON_EXISTING_ICQ_UIN_B :
return REASON_STRING_NON_EXISTING_ICQ_UIN;
case REASON_MANY_CLIENTS_FROM_SAME_IP_A :
return REASON_STRING_MANY_CLIENTS_FROM_SAME_IP;
case REASON_MANY_CLIENTS_FROM_SAME_IP_B :
return REASON_STRING_MANY_CLIENTS_FROM_SAME_IP;
case REASON_CONNECTION_RATE_EXCEEDED :
return REASON_STRING_CONNECTION_RATE_EXCEEDED;
case REASON_CONNECTION_TOO_FAST :
return REASON_STRING_CONNECTION_TOO_FAST;
case REASON_TRY_AGAIN :
return REASON_STRING_TRY_AGAIN;
default :
return REASON_STRING_NOT_SPECIFIED;
}
}
/**
* When receiving login failer
* the reasons for the failer are in the authorization
* part of the protocol ( 0x13 )
* In the AuthResponse are the possible reason codes
* here they are converted to those in the ConnectionClosedListener
* so the they can be converted to the one in service protocol events
*/
static int convertAuthCodeToReasonCode(AuthFailureInfo afi)
{
switch(afi.getErrorCode())
{
case AuthResponse.ERROR_BAD_PASSWORD :
return REASON_BAD_PASSWORD_A;
case AuthResponse.ERROR_CONNECTING_TOO_MUCH_A :
return REASON_CONNECTION_RATE_EXCEEDED;
case AuthResponse.ERROR_CONNECTING_TOO_MUCH_B : return REASON_CONNECTION_RATE_EXCEEDED;
case AuthResponse.ERROR_INVALID_SN_OR_PASS_A : return REASON_BAD_PASSWORD_A;
case AuthResponse.ERROR_INVALID_SN_OR_PASS_B : return REASON_BAD_PASSWORD_A;
// 16 is also used for blocked from same IP
case 16 : return REASON_MANY_CLIENTS_FROM_SAME_IP_A;
case AuthResponse.ERROR_SIGNON_BLOCKED : return REASON_MANY_CLIENTS_FROM_SAME_IP_B;
default : return RegistrationStateChangeEvent.REASON_NOT_SPECIFIED;
}
}
}
}

Loading…
Cancel
Save