/*
- * Copyright (c) 2008, 2009 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
static struct stream_class *stream_classes[] = {
&tcp_stream_class,
&unix_stream_class,
+#ifdef HAVE_OPENSSL
+ &ssl_stream_class,
+#endif
};
static struct pstream_class *pstream_classes[] = {
&ptcp_pstream_class,
&punix_pstream_class,
+#ifdef HAVE_OPENSSL
+ &pssl_pstream_class,
+#endif
};
/* Check the validity of the stream class structures. */
struct stream_class *class = stream_classes[i];
assert(class->name != NULL);
assert(class->open != NULL);
- if (class->close || class->recv || class->send || class->wait) {
+ if (class->close || class->recv || class->send || class->run
+ || class->run_wait || class->wait) {
assert(class->close != NULL);
assert(class->recv != NULL);
assert(class->send != NULL);
/* Prints information on active (if 'active') and passive (if 'passive')
* connection methods supported by the stream. */
void
-stream_usage(const char *name, bool active, bool passive)
+stream_usage(const char *name, bool active, bool passive,
+ bool bootstrap UNUSED)
{
/* Really this should be implemented via callbacks into the stream
* providers, but that seems too heavy-weight to bother with at the
printf("Active %s connection methods:\n", name);
printf(" tcp:IP:PORT "
"PORT at remote IP\n");
+#ifdef HAVE_OPENSSL
+ printf(" ssl:IP:PORT "
+ "SSL PORT at remote IP\n");
+#endif
printf(" unix:FILE "
"Unix domain socket named FILE\n");
}
printf("Passive %s connection methods:\n", name);
printf(" ptcp:PORT[:IP] "
"listen to TCP PORT on IP\n");
+#ifdef HAVE_OPENSSL
+ printf(" pssl:PORT[:IP] "
+ "listen for SSL on PORT on IP\n");
+#endif
printf(" punix:FILE "
"listen on Unix domain socket FILE\n");
}
+
+#ifdef HAVE_OPENSSL
+ printf("PKI configuration (required to use SSL):\n"
+ " -p, --private-key=FILE file with private key\n"
+ " -c, --certificate=FILE file with certificate for private key\n"
+ " -C, --ca-cert=FILE file with peer CA certificate\n");
+ if (bootstrap) {
+ printf(" --bootstrap-ca-cert=FILE file with peer CA certificate "
+ "to read or create\n");
+ }
+#endif
}
/* Attempts to connect a stream to a remote peer. 'name' is a connection name
error = stream_open(name, &stream);
while (error == EAGAIN) {
+ stream_run(stream);
+ stream_run_wait(stream);
stream_connect_wait(stream);
poll_block();
error = stream_connect(stream);
: (stream->class->send)(stream, buffer, n));
}
+/* Allows 'stream' to perform maintenance activities, such as flushing
+ * output buffers. */
+void
+stream_run(struct stream *stream)
+{
+ if (stream->class->run) {
+ (stream->class->run)(stream);
+ }
+}
+
+/* Arranges for the poll loop to wake up when 'stream' needs to perform
+ * maintenance activities. */
+void
+stream_run_wait(struct stream *stream)
+{
+ if (stream->class->run_wait) {
+ (stream->class->run_wait)(stream);
+ }
+}
+
+/* Arranges for the poll loop to wake up when 'stream' is ready to take an
+ * action of the given 'type'. */
void
stream_wait(struct stream *stream, enum stream_wait_type wait)
{
return retval;
}
+/* Tries to accept a new connection on 'pstream'. If successful, stores the
+ * new connection in '*new_stream' and returns 0. Otherwise, returns a
+ * positive errno value.
+ *
+ * pstream_accept_block() blocks until a connection is ready or until an error
+ * occurs. It will not return EAGAIN. */
+int
+pstream_accept_block(struct pstream *pstream, struct stream **new_stream)
+{
+ int error;
+
+ while ((error = pstream_accept(pstream, new_stream)) == EAGAIN) {
+ pstream_wait(pstream);
+ poll_block();
+ }
+ if (error) {
+ *new_stream = NULL;
+ }
+ return error;
+}
+
void
pstream_wait(struct pstream *pstream)
{
: SCS_DISCONNECTED);
stream->error = connect_status;
stream->name = xstrdup(name);
+ assert(stream->state != SCS_CONNECTING || class->connect);
}
void