/*
- * 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.
{
struct ssl_stream *sslv = ssl_stream_cast(stream);
ssl_clear_txbuf(sslv);
+
+ /* Attempt clean shutdown of the SSL connection. This will work most of
+ * the time, as long as the kernel send buffer has some free space and the
+ * SSL connection isn't renegotiating, etc. That has to be good enough,
+ * since we don't have any way to continue the close operation in the
+ * background. */
+ SSL_shutdown(sslv->ssl);
+
SSL_free(sslv->ssl);
close(sslv->fd);
free(sslv);
if (error == SSL_ERROR_ZERO_RETURN) {
return 0;
} else {
- return interpret_ssl_error("SSL_read", ret, error, &sslv->rx_want);
+ return -interpret_ssl_error("SSL_read", ret, error,
+ &sslv->rx_want);
}
}
}
struct ssl_stream *sslv = ssl_stream_cast(stream);
if (sslv->txbuf) {
- return EAGAIN;
+ return -EAGAIN;
} else {
int error;
switch (error) {
case 0:
ssl_clear_txbuf(sslv);
- return 0;
+ return n;
case EAGAIN:
leak_checker_claim(buffer);
- return 0;
+ return n;
default:
sslv->txbuf = NULL;
- return error;
+ return -error;
}
}
}
}
static int
-pssl_open(const char *name, char *suffix, struct pstream **pstreamp)
+pssl_open(const char *name UNUSED, char *suffix, struct pstream **pstreamp)
{
struct pssl_pstream *pssl;
+ struct sockaddr_in sin;
+ char bound_name[128];
int retval;
int fd;
return retval;
}
- fd = inet_open_passive(SOCK_STREAM, suffix, OFP_SSL_PORT);
+ fd = inet_open_passive(SOCK_STREAM, suffix, OFP_SSL_PORT, NULL);
if (fd < 0) {
return -fd;
}
+ sprintf(bound_name, "pssl:%"PRIu16":"IP_FMT,
+ ntohs(sin.sin_port), IP_ARGS(&sin.sin_addr.s_addr));
pssl = xmalloc(sizeof *pssl);
- pstream_init(&pssl->pstream, &pssl_pstream_class, name);
+ pstream_init(&pssl->pstream, &pssl_pstream_class, bound_name);
pssl->fd = fd;
*pstreamp = &pssl->pstream;
return 0;