You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by gs...@apache.org on 2014/11/26 21:06:00 UTC

[13/35] qpid-proton git commit: PROTON-749: Split transport into server/client sides - This allows the server and client sides of the transport to have different default behaviours. - We set the SASL client/server from the transport setting - There are

PROTON-749: Split transport into server/client sides
- This allows the server and client sides of the transport
  to have different default behaviours.
- We set the SASL client/server from the transport setting
- There are some workarounds in the tests because the full logic isn't
  implemented in proton-j, but the shared python tests must run against both.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/9c9872b5
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/9c9872b5
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/9c9872b5

Branch: refs/heads/examples
Commit: 9c9872b570664229b3199448c69fd27bf7d325bc
Parents: df02900
Author: Andrew Stitcher <as...@apache.org>
Authored: Fri Aug 15 18:25:31 2014 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Wed Nov 19 17:21:29 2014 -0500

----------------------------------------------------------------------
 proton-c/bindings/python/proton.py              | 35 ++++++++++++--------
 proton-c/include/proton/cproton.i               | 14 +-------
 proton-c/include/proton/sasl.h                  | 21 +-----------
 proton-c/include/proton/transport.h             | 20 ++++++++++-
 proton-c/src/engine/engine-internal.h           |  1 +
 proton-c/src/messenger/messenger.c              |  3 +-
 proton-c/src/posix/driver.c                     |  8 +++--
 proton-c/src/proton.c                           | 10 ++----
 proton-c/src/sasl/sasl.c                        | 33 +++++-------------
 proton-c/src/tests/engine.c                     |  3 ++
 proton-c/src/transport/transport.c              |  9 ++++-
 proton-c/src/windows/driver.c                   |  7 ++--
 .../qpid/proton/engine/impl/SaslImpl.java       |  7 +++-
 proton-j/src/main/resources/cengine.py          |  5 ++-
 proton-j/src/main/resources/csasl.py            | 14 ++++----
 tests/python/proton_tests/common.py             |  1 -
 tests/python/proton_tests/engine.py             |  3 --
 tests/python/proton_tests/sasl.py               | 14 ++------
 18 files changed, 95 insertions(+), 113 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-c/bindings/python/proton.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton.py b/proton-c/bindings/python/proton.py
index 81104f0..573ec14 100644
--- a/proton-c/bindings/python/proton.py
+++ b/proton-c/bindings/python/proton.py
@@ -2984,12 +2984,28 @@ class Transport(object):
   TRACE_FRM = PN_TRACE_FRM
   TRACE_RAW = PN_TRACE_RAW
 
-  def __init__(self, _trans=None):
-    if not _trans:
+  CLIENT = 1
+  SERVER = 2
+
+  @staticmethod
+  def _wrap_transport(c_trans):
+    if not c_trans: return None
+    wrapper = Transport(_trans=c_trans)
+    return wrapper
+
+  def __init__(self, mode=None, _trans=None):
+    if not mode and not _trans:
       self._trans = pn_transport()
-    else:
+    elif not mode:
       self._shared_trans = True
       self._trans = _trans
+    elif mode==Transport.CLIENT:
+      self._trans = pn_transport()
+    elif mode==Transport.SERVER:
+      self._trans = pn_transport()
+      pn_transport_set_server(self._trans)
+    else:
+      raise TransportException("Cannot initialise Transport from mode: %s" % str(mode))
     self._sasl = None
     self._ssl = None
 
@@ -3177,12 +3193,6 @@ class SASL(object):
   def mechanisms(self, mechs):
     pn_sasl_mechanisms(self._sasl, mechs)
 
-  def client(self):
-    pn_sasl_client(self._sasl)
-
-  def server(self):
-    pn_sasl_server(self._sasl)
-
   def allow_skip(self, allow):
     pn_sasl_allow_skip(self._sasl, allow)
 
@@ -3216,7 +3226,6 @@ class SASL(object):
   def done(self, outcome):
     pn_sasl_done(self._sasl, outcome)
 
-  STATE_CONF = PN_SASL_CONF
   STATE_IDLE = PN_SASL_IDLE
   STATE_STEP = PN_SASL_STEP
   STATE_PASS = PN_SASL_PASS
@@ -3355,7 +3364,7 @@ wrappers = {
   "pn_session": lambda x: Session._wrap_session(pn_cast_pn_session(x)),
   "pn_link": lambda x: Link._wrap_link(pn_cast_pn_link(x)),
   "pn_delivery": lambda x: Delivery._wrap_delivery(pn_cast_pn_delivery(x)),
-  "pn_transport": lambda x: Transport(pn_cast_pn_transport(x))
+  "pn_transport": lambda x: Transport._wrap_transport(pn_cast_pn_transport(x))
 }
 
 class Collector:
@@ -3590,9 +3599,7 @@ class Connector(object):
   @property
   def transport(self):
     trans = pn_connector_transport(self._cxtr)
-    if trans:
-      return Transport(trans)
-    return None
+    return Transport._wrap_transport(trans)
 
   def close(self):
     return pn_connector_close(self._cxtr)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-c/include/proton/cproton.i
----------------------------------------------------------------------
diff --git a/proton-c/include/proton/cproton.i b/proton-c/include/proton/cproton.i
index dd35c0a..3c5a1a6 100644
--- a/proton-c/include/proton/cproton.i
+++ b/proton-c/include/proton/cproton.i
@@ -87,7 +87,7 @@ typedef unsigned long int uintptr_t;
                  PN_SASL_SYS, PN_SASL_PERM, PN_SASL_TEMP, PN_SASL_SKIPPED);
 
 %aggregate_check(int, check_sasl_state,
-                 PN_SASL_CONF, PN_SASL_IDLE, PN_SASL_STEP,
+                 PN_SASL_IDLE, PN_SASL_STEP,
                  PN_SASL_PASS, PN_SASL_FAIL);
 
 
@@ -995,18 +995,6 @@ typedef unsigned long int uintptr_t;
   sasl != NULL;
 }
 
-%contract pn_sasl_client(pn_sasl_t *sasl)
-{
- require:
-  sasl != NULL;
-}
-
-%contract pn_sasl_server(pn_sasl_t *sasl)
-{
- require:
-  sasl != NULL;
-}
-
 %contract pn_sasl_allow_skip(pn_sasl_t *sasl, bool allow)
 {
  require:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-c/include/proton/sasl.h
----------------------------------------------------------------------
diff --git a/proton-c/include/proton/sasl.h b/proton-c/include/proton/sasl.h
index 84ddf10..ab64e13 100644
--- a/proton-c/include/proton/sasl.h
+++ b/proton-c/include/proton/sasl.h
@@ -60,7 +60,6 @@ typedef enum {
 
 /** The state of the SASL negotiation process */
 typedef enum {
-  PN_SASL_CONF,    /** Pending configuration by application */
   PN_SASL_IDLE,    /** Pending SASL Init */
   PN_SASL_STEP,    /** negotiation in progress */
   PN_SASL_PASS,    /** negotiation completed successfully */
@@ -96,24 +95,6 @@ PN_EXTERN void pn_sasl_mechanisms(pn_sasl_t *sasl, const char *mechanisms);
  */
 PN_EXTERN const char *pn_sasl_remote_mechanisms(pn_sasl_t *sasl);
 
-/** Configure the SASL layer to act as a SASL client.
- *
- * The role of client is similar to a TCP client - the peer requesting
- * the connection.
- *
- * @param[in] sasl the SASL layer to configure as a client
- */
-PN_EXTERN void pn_sasl_client(pn_sasl_t *sasl);
-
-/** Configure the SASL layer to act as a server.
- *
- * The role of server is similar to a TCP server - the peer accepting
- * the connection.
- *
- * @param[in] sasl the SASL layer to configure as a server
- */
-PN_EXTERN void pn_sasl_server(pn_sasl_t *sasl);
-
 /** Configure a SASL server layer to permit the client to skip the SASL exchange.
  *
  * If the peer client skips the SASL exchange (i.e. goes right to the AMQP header)
@@ -124,7 +105,7 @@ PN_EXTERN void pn_sasl_server(pn_sasl_t *sasl);
  * @param[in] sasl the SASL layer to configure
  * @param[in] allow true -> allow skip; false -> forbid skip
  */
-    PN_EXTERN void pn_sasl_allow_skip(pn_sasl_t *sasl, bool allow);
+PN_EXTERN void pn_sasl_allow_skip(pn_sasl_t *sasl, bool allow);
 
 /** Configure the SASL layer to use the "PLAIN" mechanism.
  *

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-c/include/proton/transport.h
----------------------------------------------------------------------
diff --git a/proton-c/include/proton/transport.h b/proton-c/include/proton/transport.h
index 2262e7c..537e27d 100644
--- a/proton-c/include/proton/transport.h
+++ b/proton-c/include/proton/transport.h
@@ -84,16 +84,34 @@ typedef void (*pn_tracer_t)(pn_transport_t *transport, const char *message);
 
 /**
  * Factory for creating a transport.
- *
  * A transport is used by a connection to interface with the network.
  * There can only be one connection associated with a transport. See
  * pn_transport_bind().
  *
+ * Initially a transport is configured to be a client transport. Use pn_transport_set_server()
+ * to configure the transport as a server transport.
+ *
+ * A client transport initiates outgoing connections.
+ *
+ * A client transport must be configured with the protocol layers to use and cannot
+ * configure itself automatically.
+ *
+ * A server transport accepts incoming connections. It can automatically
+ * configure itself to include the various protocol layers depending on
+ * the incoming protocol headers.
+ *
  * @return pointer to new transport
  */
 PN_EXTERN pn_transport_t *pn_transport(void);
 
 /**
+ * Configure a transport as a server
+ *
+ * @param[in] transport a transport object
+ */
+PN_EXTERN void pn_transport_set_server(pn_transport_t *transport);
+
+/**
  * Free a transport object.
  *
  * When a transport is freed, it is automatically unbound from its

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-c/src/engine/engine-internal.h
----------------------------------------------------------------------
diff --git a/proton-c/src/engine/engine-internal.h b/proton-c/src/engine/engine-internal.h
index 3960acf..ab66ef5 100644
--- a/proton-c/src/engine/engine-internal.h
+++ b/proton-c/src/engine/engine-internal.h
@@ -178,6 +178,7 @@ struct pn_transport_t {
   bool head_closed;
   bool done_processing; // if true, don't call pn_process again
   bool posted_idle_timeout;
+  bool server;
 };
 
 struct pn_connection_t {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-c/src/messenger/messenger.c
----------------------------------------------------------------------
diff --git a/proton-c/src/messenger/messenger.c b/proton-c/src/messenger/messenger.c
index f0df36a..b4d7fe2 100644
--- a/proton-c/src/messenger/messenger.c
+++ b/proton-c/src/messenger/messenger.c
@@ -328,13 +328,13 @@ static void pni_listener_readable(pn_selectable_t *sel)
   pn_socket_t sock = pn_accept(ctx->messenger->io, pn_selectable_fd(sel), name, 1024);
 
   pn_transport_t *t = pn_transport();
+  pn_transport_set_server(t);
 
   pn_ssl_t *ssl = pn_ssl(t);
   pn_ssl_init(ssl, ctx->domain, NULL);
   pn_sasl_t *sasl = pn_sasl(t);
 
   pn_sasl_mechanisms(sasl, "ANONYMOUS");
-  pn_sasl_server(sasl);
   pn_sasl_done(sasl, PN_SASL_OK);
 
   pn_connection_t *conn = pn_messenger_connection(ctx->messenger, sock, scheme, NULL, NULL, NULL, NULL, ctx);
@@ -960,7 +960,6 @@ static int pn_transport_config(pn_messenger_t *messenger,
     pn_sasl_plain(sasl, ctx->user, ctx->pass);
   } else {
     pn_sasl_mechanisms(sasl, "ANONYMOUS");
-    pn_sasl_client(sasl);
   }
 
   return 0;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-c/src/posix/driver.c
----------------------------------------------------------------------
diff --git a/proton-c/src/posix/driver.c b/proton-c/src/posix/driver.c
index 4bc71bb..fc583ec 100644
--- a/proton-c/src/posix/driver.c
+++ b/proton-c/src/posix/driver.c
@@ -208,6 +208,9 @@ pn_connector_t *pn_listener_accept(pn_listener_t *l)
     pn_connector_t *c = pn_connector_fd(l->driver, sock, NULL);
     snprintf(c->name, PN_NAME_MAX, "%s", name);
     c->listener = l;
+    c->transport = pn_transport();
+    pn_transport_set_server(c->transport);
+    c->sasl = pn_sasl(c->transport);
     return c;
   }
 }
@@ -264,6 +267,8 @@ pn_connector_t *pn_connector(pn_driver_t *driver, const char *host,
   pn_socket_t sock = pn_connect(driver->io, host, port);
 
   pn_connector_t *c = pn_connector_fd(driver, sock, context);
+  c->transport = pn_transport();
+  c->sasl = pn_sasl(c->transport);
   snprintf(c->name, PN_NAME_MAX, "%s:%s", host, port);
   if (driver->trace & (PN_TRACE_FRM | PN_TRACE_RAW | PN_TRACE_DRV))
     fprintf(stderr, "Connected to %s\n", c->name);
@@ -290,8 +295,7 @@ pn_connector_t *pn_connector_fd(pn_driver_t *driver, int fd, void *context)
   c->closed = false;
   c->wakeup = 0;
   c->connection = NULL;
-  c->transport = pn_transport();
-  c->sasl = pn_sasl(c->transport);
+  c->transport = NULL;
   c->input_done = false;
   c->output_done = false;
   c->context = context;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-c/src/proton.c
----------------------------------------------------------------------
diff --git a/proton-c/src/proton.c b/proton-c/src/proton.c
index 495659a..6e4f69d 100644
--- a/proton-c/src/proton.c
+++ b/proton-c/src/proton.c
@@ -132,11 +132,8 @@ void server_callback(pn_connector_t *ctor)
   while (pn_sasl_state(sasl) != PN_SASL_PASS) {
     switch (pn_sasl_state(sasl)) {
     case PN_SASL_IDLE:
-      return;
-    case PN_SASL_CONF:
       pn_sasl_mechanisms(sasl, "PLAIN ANONYMOUS");
-      pn_sasl_server(sasl);
-      break;
+      return;
     case PN_SASL_STEP:
       {
         size_t n = pn_sasl_pending(sasl);
@@ -283,15 +280,12 @@ void client_callback(pn_connector_t *ctor)
     pn_sasl_state_t st = pn_sasl_state(sasl);
     switch (st) {
     case PN_SASL_IDLE:
-      return;
-    case PN_SASL_CONF:
       if (ctx->mechanism && !strcmp(ctx->mechanism, "PLAIN")) {
         pn_sasl_plain(sasl, ctx->username, ctx->password);
       } else {
         pn_sasl_mechanisms(sasl, ctx->mechanism);
-        pn_sasl_client(sasl);
       }
-      break;
+      return;
     case PN_SASL_STEP:
       if (pn_sasl_pending(sasl)) {
         fprintf(stderr, "challenge failed\n");

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-c/src/sasl/sasl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/sasl/sasl.c b/proton-c/src/sasl/sasl.c
index ffa310b..90adcf6 100644
--- a/proton-c/src/sasl/sasl.c
+++ b/proton-c/src/sasl/sasl.c
@@ -42,7 +42,6 @@ struct pni_sasl_t {
   pn_buffer_t *recv_data;
   pn_sasl_outcome_t outcome;
   bool client;
-  bool configured;
   bool allow_skip;
   bool sent_init;
   bool rcvd_init;
@@ -104,8 +103,7 @@ pn_sasl_t *pn_sasl(pn_transport_t *transport)
     sasl->disp = pn_dispatcher(1, transport);
     sasl->disp->batch = false;
 
-    sasl->client = false;
-    sasl->configured = false;
+    sasl->client = !transport->server;
     sasl->mechanisms = NULL;
     sasl->remote_mechanisms = NULL;
     sasl->send_data = pn_buffer(16);
@@ -131,7 +129,6 @@ pn_sasl_state_t pn_sasl_state(pn_sasl_t *sasl0)
 {
   pni_sasl_t *sasl = get_sasl_internal(sasl0);
   if (sasl) {
-    if (!sasl->configured) return PN_SASL_CONF;
     if (sasl->outcome == PN_SASL_NONE) {
       return sasl->rcvd_init ? PN_SASL_STEP : PN_SASL_IDLE;
     } else {
@@ -200,24 +197,6 @@ ssize_t pn_sasl_recv(pn_sasl_t *sasl0, char *bytes, size_t size)
   }
 }
 
-void pn_sasl_client(pn_sasl_t *sasl0)
-{
-  pni_sasl_t *sasl = get_sasl_internal(sasl0);
-  if (sasl) {
-    sasl->client = true;
-    sasl->configured = true;
-  }
-}
-
-void pn_sasl_server(pn_sasl_t *sasl0)
-{
-  pni_sasl_t *sasl = get_sasl_internal(sasl0);
-  if (sasl) {
-    sasl->client = false;
-    sasl->configured = true;
-  }
-}
-
 void pn_sasl_allow_skip(pn_sasl_t *sasl0, bool allow)
 {
   pni_sasl_t *sasl = get_sasl_internal(sasl0);
@@ -244,7 +223,6 @@ void pn_sasl_plain(pn_sasl_t *sasl0, const char *username, const char *password)
 
   pn_sasl_mechanisms(sasl0, "PLAIN");
   pn_sasl_send(sasl0, iresp, size);
-  pn_sasl_client(sasl0);
   free(iresp);
 }
 
@@ -253,6 +231,13 @@ void pn_sasl_done(pn_sasl_t *sasl0, pn_sasl_outcome_t outcome)
   pni_sasl_t *sasl = get_sasl_internal(sasl0);
   if (sasl) {
     sasl->outcome = outcome;
+    // If we do this on the client it is a hack to tell us that
+    // no actual negatiation is going to happen and we can go
+    // straight to the AMQP layer
+    if (sasl->client) {
+      sasl->rcvd_done = true;
+      sasl->sent_done = true;
+    }
   }
 }
 
@@ -330,8 +315,6 @@ void pn_server_done(pn_sasl_t *sasl0)
 void pn_sasl_process(pn_transport_t *transport)
 {
   pni_sasl_t *sasl = transport->sasl;
-  if (!sasl->configured) return;
-
   if (!sasl->sent_init) {
     if (sasl->client) {
       pn_client_init(sasl);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-c/src/tests/engine.c
----------------------------------------------------------------------
diff --git a/proton-c/src/tests/engine.c b/proton-c/src/tests/engine.c
index e10e13f..87d8d95 100644
--- a/proton-c/src/tests/engine.c
+++ b/proton-c/src/tests/engine.c
@@ -129,6 +129,7 @@ int test_free_connection(int argc, char **argv)
 
     pn_connection_t *c2 = pn_connection();
     pn_transport_t  *t2 = pn_transport();
+    pn_transport_set_server(t2);
     pn_transport_bind(t2, c2);
 
     //pn_transport_trace(t1, PN_TRACE_FRM);
@@ -181,6 +182,7 @@ int test_free_session(int argc, char **argv)
 
     pn_connection_t *c2 = pn_connection();
     pn_transport_t  *t2 = pn_transport();
+    pn_transport_set_server(t2);
     pn_transport_bind(t2, c2);
 
     //pn_transport_trace(t1, PN_TRACE_FRM);
@@ -243,6 +245,7 @@ int test_free_link(int argc, char **argv)
 
     pn_connection_t *c2 = pn_connection();
     pn_transport_t  *t2 = pn_transport();
+    pn_transport_set_server(t2);
     pn_transport_bind(t2, c2);
 
     //pn_transport_trace(t1, PN_TRACE_FRM);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-c/src/transport/transport.c
----------------------------------------------------------------------
diff --git a/proton-c/src/transport/transport.c b/proton-c/src/transport/transport.c
index 865f8c9..2d5f93a 100644
--- a/proton-c/src/transport/transport.c
+++ b/proton-c/src/transport/transport.c
@@ -199,6 +199,8 @@ static void pn_transport_initialize(void *object)
   transport->done_processing = false;
 
   transport->posted_idle_timeout = false;
+
+  transport->server = false;
 }
 
 pn_session_t *pn_channel_state(pn_transport_t *transport, uint16_t channel)
@@ -232,7 +234,7 @@ static void pn_transport_finalize(void *object);
 #define pn_transport_compare NULL
 #define pn_transport_inspect NULL
 
-pn_transport_t *pn_transport()
+pn_transport_t *pn_transport(void)
 {
   static const pn_class_t clazz = PN_CLASS(pn_transport);
   pn_transport_t *transport =
@@ -253,6 +255,11 @@ pn_transport_t *pn_transport()
   return transport;
 }
 
+void pn_transport_set_server(pn_transport_t *transport)
+{
+  transport->server = true;
+}
+
 void pn_transport_free(pn_transport_t *transport)
 {
   if (!transport) return;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-c/src/windows/driver.c
----------------------------------------------------------------------
diff --git a/proton-c/src/windows/driver.c b/proton-c/src/windows/driver.c
index 43662f9..013b422 100644
--- a/proton-c/src/windows/driver.c
+++ b/proton-c/src/windows/driver.c
@@ -285,6 +285,8 @@ pn_connector_t *pn_listener_accept(pn_listener_t *l)
     pn_connector_t *c = pn_connector_fd(l->driver, sock, NULL);
     snprintf(c->name, PN_NAME_MAX, "%s", name);
     c->listener = l;
+    c->transport = pn_transport_server();
+    c->sasl = pn_sasl(c->transport);
     return c;
   }
 }
@@ -383,6 +385,8 @@ pn_connector_t *pn_connector(pn_driver_t *driver, const char *host,
 
   pn_socket_t sock = pn_connect(driver->io, host, port);
   pn_connector_t *c = pn_connector_fd(driver, sock, context);
+  c->transport = pn_transport_client();
+  c->sasl = pn_sasl(c->transport);
   snprintf(c->name, PN_NAME_MAX, "%s:%s", host, port);
   if (driver->trace & (PN_TRACE_FRM | PN_TRACE_RAW | PN_TRACE_DRV))
     fprintf(stderr, "Connected to %s\n", c->name);
@@ -412,8 +416,7 @@ pn_connector_t *pn_connector_fd(pn_driver_t *driver, pn_socket_t fd, void *conte
   c->wakeup = 0;
   c->posted_wakeup = 0;
   c->connection = NULL;
-  c->transport = pn_transport();
-  c->sasl = pn_sasl(c->transport);
+  c->transport = NULL;
   c->input_done = false;
   c->output_done = false;
   c->context = context;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/SaslImpl.java
----------------------------------------------------------------------
diff --git a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/SaslImpl.java b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/SaslImpl.java
index d587abb..1a933bf 100644
--- a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/SaslImpl.java
+++ b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/SaslImpl.java
@@ -340,7 +340,12 @@ public class SaslImpl implements Sasl, SaslFrameBody.SaslFrameBodyHandler<Void>,
     @Override
     public void done(SaslOutcome outcome)
     {
-        checkRole(Role.SERVER);
+        // Support current hack in C code to allow producing sasl frames for
+        // ANONYMOUS in a single chunk
+        if(_role == Role.CLIENT)
+        {
+            return;
+        }
         _outcome = outcome;
         _done = true;
         _state = classifyStateFromOutcome(outcome);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-j/src/main/resources/cengine.py
----------------------------------------------------------------------
diff --git a/proton-j/src/main/resources/cengine.py b/proton-j/src/main/resources/cengine.py
index f9d4ddb..8f25a0e 100644
--- a/proton-j/src/main/resources/cengine.py
+++ b/proton-j/src/main/resources/cengine.py
@@ -865,14 +865,17 @@ def pn_delivery_settle(dlv):
   dlv.impl.settle()
 
 class pn_transport_wrapper:
-
   def __init__(self, impl):
     self.impl = impl
+    self.server = False
     self.condition = pn_condition()
 
 def pn_transport():
   return wrap(Proton.transport(), pn_transport_wrapper)
 
+def pn_transport_set_server(trans):
+  trans.server = True;
+
 def pn_transport_get_max_frame(trans):
   return trans.impl.getMaxFrameSize()
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/proton-j/src/main/resources/csasl.py
----------------------------------------------------------------------
diff --git a/proton-j/src/main/resources/csasl.py b/proton-j/src/main/resources/csasl.py
index a24246d..fe184d8 100644
--- a/proton-j/src/main/resources/csasl.py
+++ b/proton-j/src/main/resources/csasl.py
@@ -38,10 +38,14 @@ PN_SASL_PASS = 3
 PN_SASL_FAIL = 4
 
 def pn_sasl(tp):
-  return tp.impl.sasl()
+  sasl = tp.impl.sasl()
+  if tp.server:
+    sasl.server()
+  else:
+    sasl.client()
+  return sasl
 
 SASL_STATES = {
-  Sasl.SaslState.PN_SASL_CONF: PN_SASL_CONF,
   Sasl.SaslState.PN_SASL_IDLE: PN_SASL_IDLE,
   Sasl.SaslState.PN_SASL_STEP: PN_SASL_STEP,
   Sasl.SaslState.PN_SASL_PASS: PN_SASL_PASS,
@@ -74,12 +78,6 @@ def pn_sasl_state(sasl):
 def pn_sasl_mechanisms(sasl, mechs):
   sasl.setMechanisms(*mechs.split())
 
-def pn_sasl_client(sasl):
-  sasl.client()
-
-def pn_sasl_server(sasl):
-  sasl.server()
-
 def pn_sasl_allow_skip(sasl, allow):
   sasl.allowSkip(allow)
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/tests/python/proton_tests/common.py
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/common.py b/tests/python/proton_tests/common.py
index e0887e6..d159214 100644
--- a/tests/python/proton_tests/common.py
+++ b/tests/python/proton_tests/common.py
@@ -178,7 +178,6 @@ class TestServer(object):
     """
     sasl = cxtr.sasl()
     sasl.mechanisms("ANONYMOUS")
-    sasl.server()
     cxtr.connection = Connection()
     if "idle_timeout" in self.args:
       cxtr.transport.idle_timeout = self.args["idle_timeout"]

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/tests/python/proton_tests/engine.py
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/engine.py b/tests/python/proton_tests/engine.py
index d17a57c..6a07aea 100644
--- a/tests/python/proton_tests/engine.py
+++ b/tests/python/proton_tests/engine.py
@@ -1823,7 +1823,6 @@ class ServerTest(Test):
     self.cxtr = self.driver.connector(self.server.host, self.server.port)
     self.cxtr.transport.idle_timeout = idle_timeout_secs
     self.cxtr.sasl().mechanisms("ANONYMOUS")
-    self.cxtr.sasl().client()
     self.conn = Connection()
     self.cxtr.connection = self.conn
     self.conn.open()
@@ -1869,7 +1868,6 @@ class ServerTest(Test):
     self.driver = Driver()
     self.cxtr = self.driver.connector(self.server.host, self.server.port)
     self.cxtr.sasl().mechanisms("ANONYMOUS")
-    self.cxtr.sasl().client()
     self.conn = Connection()
     self.cxtr.connection = self.conn
     self.conn.open()
@@ -2438,5 +2436,4 @@ class IdleTimeoutEventTest(PeerTest):
 
   def testTimeoutWithZombieServerAndSASL(self):
     sasl = self.transport.sasl()
-    sasl.client()
     self.testTimeoutWithZombieServer()

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9c9872b5/tests/python/proton_tests/sasl.py
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/sasl.py b/tests/python/proton_tests/sasl.py
index 5e353d5..c2dc005 100644
--- a/tests/python/proton_tests/sasl.py
+++ b/tests/python/proton_tests/sasl.py
@@ -29,7 +29,7 @@ class SaslTest(Test):
   def setup(self):
     self.t1 = Transport()
     self.s1 = SASL(self.t1)
-    self.t2 = Transport()
+    self.t2 = Transport(Transport.SERVER)
     self.s2 = SASL(self.t2)
 
   def pump(self):
@@ -37,12 +37,10 @@ class SaslTest(Test):
 
   def testPipelined(self):
     self.s1.mechanisms("ANONYMOUS")
-    self.s1.client()
 
     assert self.s1.outcome is None
 
     self.s2.mechanisms("ANONYMOUS")
-    self.s2.server()
     self.s2.done(SASL.OK)
 
     out1 = self.t1.peek(1024)
@@ -60,13 +58,13 @@ class SaslTest(Test):
 
   def testSaslAndAmqpInSingleChunk(self):
     self.s1.mechanisms("ANONYMOUS")
-    self.s1.client()
+    self.s1.done(SASL.OK)
 
     self.s2.mechanisms("ANONYMOUS")
-    self.s2.server()
     self.s2.done(SASL.OK)
 
     # send the server's OK to the client
+    # This is still needed for the Java impl
     out2 = self.t2.peek(1024)
     self.t2.pop(len(out2))
     self.t1.push(out2)
@@ -106,9 +104,7 @@ class SaslTest(Test):
 
   def testChallengeResponse(self):
     self.s1.mechanisms("FAKE_MECH")
-    self.s1.client()
     self.s2.mechanisms("FAKE_MECH")
-    self.s2.server()
     self.pump()
     challenge = "Who goes there!"
     self.s2.send(challenge)
@@ -130,14 +126,12 @@ class SaslTest(Test):
 
   def testPipelined2(self):
     self.s1.mechanisms("ANONYMOUS")
-    self.s1.client()
 
     out1 = self.t1.peek(1024)
     self.t1.pop(len(out1))
     self.t2.push(out1)
 
     self.s2.mechanisms("ANONYMOUS")
-    self.s2.server()
     self.s2.done(SASL.OK)
     c2 = Connection()
     c2.open()
@@ -154,7 +148,6 @@ class SaslTest(Test):
     """ PROTON-235
     """
     self.s1.mechanisms("ANONYMOUS")
-    self.s1.client()
     assert self.s1.outcome is None
 
     # self.t1.trace(Transport.TRACE_FRM)
@@ -196,7 +189,6 @@ class SaslTest(Test):
     """Verify that the server (with SASL) correctly handles a client without SASL"""
     self.t1 = Transport()
     self.s2.mechanisms("ANONYMOUS")
-    self.s2.server()
     self.s2.allow_skip(True)
     self.pump()
     assert self.s2.outcome == SASL.SKIPPED


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org