
zmq.io.mechanism.plain.PlainClientMechanism Maven / Gradle / Ivy
package zmq.io.mechanism.plain;
import static zmq.io.Metadata.IDENTITY;
import static zmq.io.Metadata.SOCKET_TYPE;
import zmq.Msg;
import zmq.Options;
import zmq.ZError;
import zmq.ZMQ;
import zmq.io.SessionBase;
import zmq.io.mechanism.Mechanism;
public class PlainClientMechanism extends Mechanism
{
private enum State
{
SENDING_HELLO,
WAITING_FOR_WELCOME,
SENDING_INITIATE,
WAITING_FOR_READY,
ERROR_COMMAND_RECEIVED,
READY
}
private State state;
public PlainClientMechanism(SessionBase session, Options options)
{
super(session, null, options);
this.state = State.SENDING_HELLO;
}
@Override
public int nextHandshakeCommand(Msg msg)
{
int rc;
switch (state) {
case SENDING_HELLO:
rc = produceHello(msg);
if (rc == 0) {
state = State.WAITING_FOR_WELCOME;
}
break;
case SENDING_INITIATE:
rc = produceInitiate(msg);
if (rc == 0) {
state = State.WAITING_FOR_READY;
}
break;
default:
rc = ZError.EAGAIN;
break;
}
return rc;
}
@Override
public int processHandshakeCommand(Msg msg)
{
int rc;
int dataSize = msg.size();
if (dataSize >= 8 && compare(msg, "WELCOME", true)) {
rc = processWelcome(msg);
}
else if (dataSize >= 6 && compare(msg, "READY", true)) {
rc = processReady(msg);
}
else if (dataSize >= 6 && compare(msg, "ERROR", true)) {
rc = processError(msg);
}
else {
// Temporary support for security debugging
System.out.println("PLAIN Client I: invalid handshake command");
rc = ZError.EPROTO;
}
return rc;
}
@Override
public Status status()
{
if (state == State.READY) {
return Status.READY;
}
else if (state == State.ERROR_COMMAND_RECEIVED) {
return Status.ERROR;
}
else {
return Status.HANDSHAKING;
}
}
@Override
public int zapMsgAvailable()
{
return 0;
}
private int produceHello(Msg msg)
{
String plainUsername = options.plainUsername;
assert (plainUsername.length() < 256);
String plainPassword = options.plainPassword;
assert (plainPassword.length() < 256);
msg.putShortString("HELLO");
msg.putShortString(plainUsername);
msg.putShortString(plainPassword);
return 0;
}
private int processWelcome(Msg msg)
{
if (state != State.WAITING_FOR_WELCOME) {
return ZError.EPROTO;
}
if (msg.size() != 8) {
return ZError.EPROTO;
}
state = State.SENDING_INITIATE;
return 0;
}
private int produceInitiate(Msg msg)
{
// Add mechanism string
msg.putShortString("INITIATE");
// Add socket type property
String socketType = socketType();
addProperty(msg, SOCKET_TYPE, socketType);
// Add identity property
if (options.type == ZMQ.ZMQ_REQ || options.type == ZMQ.ZMQ_DEALER || options.type == ZMQ.ZMQ_ROUTER) {
addProperty(msg, IDENTITY, options.identity);
}
return 0;
}
private int processReady(Msg msg)
{
if (state != State.WAITING_FOR_READY) {
return ZError.EPROTO;
}
int rc = parseMetadata(msg, 6, false);
if (rc == 0) {
state = State.READY;
}
return rc;
}
private int processError(Msg msg)
{
if (state != State.WAITING_FOR_WELCOME && state != State.WAITING_FOR_READY) {
session.getSocket().eventHandshakeFailedProtocol(session.getEndpoint(), ZMQ.ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
return ZError.EPROTO;
}
state = State.ERROR_COMMAND_RECEIVED;
return parseErrorMessage(msg);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy