]> git.proxmox.com Git - mirror_ovs.git/blame - lib/stream.c
hash: Replace primary hash functions by murmurhash.
[mirror_ovs.git] / lib / stream.c
CommitLineData
c34b65c7 1/*
982697a4 2 * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
c34b65c7
BP
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <config.h>
18#include "stream-provider.h"
c34b65c7
BP
19#include <errno.h>
20#include <inttypes.h>
21#include <netinet/in.h>
22#include <poll.h>
23#include <stdlib.h>
24#include <string.h>
25#include "coverage.h"
26#include "dynamic-string.h"
b302749b 27#include "fatal-signal.h"
c34b65c7
BP
28#include "flow.h"
29#include "ofp-print.h"
30#include "ofpbuf.h"
31#include "openflow/nicira-ext.h"
32#include "openflow/openflow.h"
33#include "packets.h"
34#include "poll-loop.h"
35#include "random.h"
36#include "util.h"
c34b65c7
BP
37#include "vlog.h"
38
d98e6007 39VLOG_DEFINE_THIS_MODULE(stream);
5136ce49 40
d76f09ea
BP
41COVERAGE_DEFINE(pstream_open);
42COVERAGE_DEFINE(stream_open);
43
c34b65c7
BP
44/* State of an active stream.*/
45enum stream_state {
46 SCS_CONNECTING, /* Underlying stream is not connected. */
47 SCS_CONNECTED, /* Connection established. */
48 SCS_DISCONNECTED /* Connection failed or connection closed. */
49};
50
da327b18 51static const struct stream_class *stream_classes[] = {
c34b65c7
BP
52 &tcp_stream_class,
53 &unix_stream_class,
55709289
BP
54#ifdef HAVE_OPENSSL
55 &ssl_stream_class,
56#endif
c34b65c7
BP
57};
58
da327b18 59static const struct pstream_class *pstream_classes[] = {
c34b65c7
BP
60 &ptcp_pstream_class,
61 &punix_pstream_class,
55709289
BP
62#ifdef HAVE_OPENSSL
63 &pssl_pstream_class,
64#endif
c34b65c7
BP
65};
66
67/* Check the validity of the stream class structures. */
68static void
69check_stream_classes(void)
70{
71#ifndef NDEBUG
72 size_t i;
73
74 for (i = 0; i < ARRAY_SIZE(stream_classes); i++) {
da327b18 75 const struct stream_class *class = stream_classes[i];
cb22974d
BP
76 ovs_assert(class->name != NULL);
77 ovs_assert(class->open != NULL);
539e96f6
BP
78 if (class->close || class->recv || class->send || class->run
79 || class->run_wait || class->wait) {
cb22974d
BP
80 ovs_assert(class->close != NULL);
81 ovs_assert(class->recv != NULL);
82 ovs_assert(class->send != NULL);
83 ovs_assert(class->wait != NULL);
c34b65c7
BP
84 } else {
85 /* This class delegates to another one. */
86 }
87 }
88
89 for (i = 0; i < ARRAY_SIZE(pstream_classes); i++) {
da327b18 90 const struct pstream_class *class = pstream_classes[i];
cb22974d
BP
91 ovs_assert(class->name != NULL);
92 ovs_assert(class->listen != NULL);
c34b65c7 93 if (class->close || class->accept || class->wait) {
cb22974d
BP
94 ovs_assert(class->close != NULL);
95 ovs_assert(class->accept != NULL);
96 ovs_assert(class->wait != NULL);
c34b65c7
BP
97 } else {
98 /* This class delegates to another one. */
99 }
100 }
101#endif
102}
103
104/* Prints information on active (if 'active') and passive (if 'passive')
105 * connection methods supported by the stream. */
106void
9467fe62 107stream_usage(const char *name, bool active, bool passive,
c69ee87c 108 bool bootstrap OVS_UNUSED)
c34b65c7
BP
109{
110 /* Really this should be implemented via callbacks into the stream
111 * providers, but that seems too heavy-weight to bother with at the
112 * moment. */
113
114 printf("\n");
115 if (active) {
116 printf("Active %s connection methods:\n", name);
117 printf(" tcp:IP:PORT "
118 "PORT at remote IP\n");
9467fe62
BP
119#ifdef HAVE_OPENSSL
120 printf(" ssl:IP:PORT "
121 "SSL PORT at remote IP\n");
122#endif
c34b65c7
BP
123 printf(" unix:FILE "
124 "Unix domain socket named FILE\n");
125 }
126
127 if (passive) {
128 printf("Passive %s connection methods:\n", name);
129 printf(" ptcp:PORT[:IP] "
130 "listen to TCP PORT on IP\n");
9467fe62
BP
131#ifdef HAVE_OPENSSL
132 printf(" pssl:PORT[:IP] "
133 "listen for SSL on PORT on IP\n");
134#endif
c34b65c7
BP
135 printf(" punix:FILE "
136 "listen on Unix domain socket FILE\n");
137 }
9467fe62
BP
138
139#ifdef HAVE_OPENSSL
140 printf("PKI configuration (required to use SSL):\n"
141 " -p, --private-key=FILE file with private key\n"
142 " -c, --certificate=FILE file with certificate for private key\n"
143 " -C, --ca-cert=FILE file with peer CA certificate\n");
144 if (bootstrap) {
145 printf(" --bootstrap-ca-cert=FILE file with peer CA certificate "
146 "to read or create\n");
147 }
148#endif
c34b65c7
BP
149}
150
26ad129e
BP
151/* Given 'name', a stream name in the form "TYPE:ARGS", stores the class
152 * named "TYPE" into '*classp' and returns 0. Returns EAFNOSUPPORT and stores
153 * a null pointer into '*classp' if 'name' is in the wrong form or if no such
154 * class exists. */
155static int
da327b18 156stream_lookup_class(const char *name, const struct stream_class **classp)
c34b65c7
BP
157{
158 size_t prefix_len;
159 size_t i;
160
c34b65c7
BP
161 check_stream_classes();
162
26ad129e 163 *classp = NULL;
c34b65c7 164 prefix_len = strcspn(name, ":");
26ad129e 165 if (name[prefix_len] == '\0') {
c34b65c7
BP
166 return EAFNOSUPPORT;
167 }
168 for (i = 0; i < ARRAY_SIZE(stream_classes); i++) {
da327b18 169 const struct stream_class *class = stream_classes[i];
c34b65c7
BP
170 if (strlen(class->name) == prefix_len
171 && !memcmp(class->name, name, prefix_len)) {
26ad129e
BP
172 *classp = class;
173 return 0;
c34b65c7
BP
174 }
175 }
176 return EAFNOSUPPORT;
177}
178
26ad129e
BP
179/* Returns 0 if 'name' is a stream name in the form "TYPE:ARGS" and TYPE is
180 * a supported stream type, otherwise EAFNOSUPPORT. */
181int
182stream_verify_name(const char *name)
183{
da327b18 184 const struct stream_class *class;
26ad129e
BP
185 return stream_lookup_class(name, &class);
186}
187
188/* Attempts to connect a stream to a remote peer. 'name' is a connection name
189 * in the form "TYPE:ARGS", where TYPE is an active stream class's name and
190 * ARGS are stream class-specific.
191 *
192 * Returns 0 if successful, otherwise a positive errno value. If successful,
193 * stores a pointer to the new connection in '*streamp', otherwise a null
194 * pointer. */
195int
f125905c 196stream_open(const char *name, struct stream **streamp, uint8_t dscp)
26ad129e 197{
da327b18 198 const struct stream_class *class;
26ad129e
BP
199 struct stream *stream;
200 char *suffix_copy;
201 int error;
202
203 COVERAGE_INC(stream_open);
204
205 /* Look up the class. */
206 error = stream_lookup_class(name, &class);
207 if (!class) {
208 goto error;
209 }
210
211 /* Call class's "open" function. */
212 suffix_copy = xstrdup(strchr(name, ':') + 1);
f125905c 213 error = class->open(name, suffix_copy, &stream, dscp);
26ad129e
BP
214 free(suffix_copy);
215 if (error) {
216 goto error;
217 }
218
219 /* Success. */
220 *streamp = stream;
221 return 0;
222
223error:
224 *streamp = NULL;
225 return error;
226}
227
766407ea
BP
228/* Blocks until a previously started stream connection attempt succeeds or
229 * fails. 'error' should be the value returned by stream_open() and 'streamp'
230 * should point to the stream pointer set by stream_open(). Returns 0 if
231 * successful, otherwise a positive errno value other than EAGAIN or
232 * EINPROGRESS. If successful, leaves '*streamp' untouched; on error, closes
233 * '*streamp' and sets '*streamp' to null.
234 *
235 * Typical usage:
236 * error = stream_open_block(stream_open("tcp:1.2.3.4:5", &stream), &stream);
237 */
c34b65c7 238int
766407ea 239stream_open_block(int error, struct stream **streamp)
c34b65c7 240{
766407ea 241 struct stream *stream = *streamp;
c34b65c7 242
b302749b
BP
243 fatal_signal_run();
244
b0bfeb3e
BP
245 if (!error) {
246 while ((error = stream_connect(stream)) == EAGAIN) {
247 stream_run(stream);
248 stream_run_wait(stream);
249 stream_connect_wait(stream);
250 poll_block();
251 }
cb22974d 252 ovs_assert(error != EINPROGRESS);
c34b65c7 253 }
b0bfeb3e 254
c34b65c7
BP
255 if (error) {
256 stream_close(stream);
257 *streamp = NULL;
258 } else {
259 *streamp = stream;
260 }
261 return error;
262}
263
264/* Closes 'stream'. */
265void
266stream_close(struct stream *stream)
267{
268 if (stream != NULL) {
269 char *name = stream->name;
270 (stream->class->close)(stream);
271 free(name);
272 }
273}
274
275/* Returns the name of 'stream', that is, the string passed to
276 * stream_open(). */
277const char *
278stream_get_name(const struct stream *stream)
279{
280 return stream ? stream->name : "(null)";
281}
282
283/* Returns the IP address of the peer, or 0 if the peer is not connected over
284 * an IP-based protocol or if its IP address is not yet known. */
4408d18a 285ovs_be32
c34b65c7
BP
286stream_get_remote_ip(const struct stream *stream)
287{
288 return stream->remote_ip;
289}
290
291/* Returns the transport port of the peer, or 0 if the connection does not
292 * contain a port or if the port is not yet known. */
4408d18a 293ovs_be16
c34b65c7
BP
294stream_get_remote_port(const struct stream *stream)
295{
296 return stream->remote_port;
297}
298
299/* Returns the IP address used to connect to the peer, or 0 if the connection
300 * is not an IP-based protocol or if its IP address is not yet known. */
4408d18a 301ovs_be32
c34b65c7
BP
302stream_get_local_ip(const struct stream *stream)
303{
304 return stream->local_ip;
305}
306
307/* Returns the transport port used to connect to the peer, or 0 if the
308 * connection does not contain a port or if the port is not yet known. */
4408d18a 309ovs_be16
c34b65c7
BP
310stream_get_local_port(const struct stream *stream)
311{
312 return stream->local_port;
313}
314
315static void
316scs_connecting(struct stream *stream)
317{
318 int retval = (stream->class->connect)(stream);
cb22974d 319 ovs_assert(retval != EINPROGRESS);
c34b65c7
BP
320 if (!retval) {
321 stream->state = SCS_CONNECTED;
322 } else if (retval != EAGAIN) {
323 stream->state = SCS_DISCONNECTED;
324 stream->error = retval;
325 }
326}
327
294e9fc8
BP
328/* Tries to complete the connection on 'stream'. If 'stream''s connection is
329 * complete, returns 0 if the connection was successful or a positive errno
330 * value if it failed. If the connection is still in progress, returns
331 * EAGAIN. */
c34b65c7
BP
332int
333stream_connect(struct stream *stream)
334{
335 enum stream_state last_state;
336
337 do {
338 last_state = stream->state;
339 switch (stream->state) {
340 case SCS_CONNECTING:
341 scs_connecting(stream);
342 break;
343
344 case SCS_CONNECTED:
345 return 0;
346
347 case SCS_DISCONNECTED:
348 return stream->error;
349
350 default:
351 NOT_REACHED();
352 }
353 } while (stream->state != last_state);
354
355 return EAGAIN;
356}
357
358/* Tries to receive up to 'n' bytes from 'stream' into 'buffer', and returns:
359 *
360 * - If successful, the number of bytes received (between 1 and 'n').
361 *
362 * - On error, a negative errno value.
363 *
364 * - 0, if the connection has been closed in the normal fashion, or if 'n'
365 * is zero.
366 *
367 * The recv function will not block waiting for a packet to arrive. If no
368 * data have been received, it returns -EAGAIN immediately. */
369int
370stream_recv(struct stream *stream, void *buffer, size_t n)
371{
372 int retval = stream_connect(stream);
373 return (retval ? -retval
374 : n == 0 ? 0
375 : (stream->class->recv)(stream, buffer, n));
376}
377
378/* Tries to send up to 'n' bytes of 'buffer' on 'stream', and returns:
379 *
380 * - If successful, the number of bytes sent (between 1 and 'n'). 0 is
381 * only a valid return value if 'n' is 0.
382 *
383 * - On error, a negative errno value.
384 *
385 * The send function will not block. If no bytes can be immediately accepted
386 * for transmission, it returns -EAGAIN immediately. */
387int
388stream_send(struct stream *stream, const void *buffer, size_t n)
389{
390 int retval = stream_connect(stream);
391 return (retval ? -retval
392 : n == 0 ? 0
393 : (stream->class->send)(stream, buffer, n));
394}
395
539e96f6
BP
396/* Allows 'stream' to perform maintenance activities, such as flushing
397 * output buffers. */
398void
399stream_run(struct stream *stream)
400{
401 if (stream->class->run) {
402 (stream->class->run)(stream);
403 }
404}
405
406/* Arranges for the poll loop to wake up when 'stream' needs to perform
407 * maintenance activities. */
408void
409stream_run_wait(struct stream *stream)
410{
411 if (stream->class->run_wait) {
412 (stream->class->run_wait)(stream);
413 }
414}
415
416/* Arranges for the poll loop to wake up when 'stream' is ready to take an
417 * action of the given 'type'. */
c34b65c7
BP
418void
419stream_wait(struct stream *stream, enum stream_wait_type wait)
420{
cb22974d
BP
421 ovs_assert(wait == STREAM_CONNECT || wait == STREAM_RECV
422 || wait == STREAM_SEND);
c34b65c7
BP
423
424 switch (stream->state) {
425 case SCS_CONNECTING:
426 wait = STREAM_CONNECT;
427 break;
428
429 case SCS_DISCONNECTED:
430 poll_immediate_wake();
431 return;
432 }
433 (stream->class->wait)(stream, wait);
434}
435
436void
437stream_connect_wait(struct stream *stream)
438{
439 stream_wait(stream, STREAM_CONNECT);
440}
441
442void
443stream_recv_wait(struct stream *stream)
444{
445 stream_wait(stream, STREAM_RECV);
446}
447
448void
449stream_send_wait(struct stream *stream)
450{
451 stream_wait(stream, STREAM_SEND);
452}
453
26ad129e
BP
454/* Given 'name', a pstream name in the form "TYPE:ARGS", stores the class
455 * named "TYPE" into '*classp' and returns 0. Returns EAFNOSUPPORT and stores
456 * a null pointer into '*classp' if 'name' is in the wrong form or if no such
457 * class exists. */
458static int
da327b18 459pstream_lookup_class(const char *name, const struct pstream_class **classp)
c34b65c7
BP
460{
461 size_t prefix_len;
462 size_t i;
463
464 check_stream_classes();
465
26ad129e 466 *classp = NULL;
c34b65c7 467 prefix_len = strcspn(name, ":");
26ad129e 468 if (name[prefix_len] == '\0') {
c34b65c7
BP
469 return EAFNOSUPPORT;
470 }
471 for (i = 0; i < ARRAY_SIZE(pstream_classes); i++) {
da327b18 472 const struct pstream_class *class = pstream_classes[i];
c34b65c7
BP
473 if (strlen(class->name) == prefix_len
474 && !memcmp(class->name, name, prefix_len)) {
26ad129e
BP
475 *classp = class;
476 return 0;
c34b65c7
BP
477 }
478 }
479 return EAFNOSUPPORT;
480}
481
26ad129e
BP
482/* Returns 0 if 'name' is a pstream name in the form "TYPE:ARGS" and TYPE is
483 * a supported pstream type, otherwise EAFNOSUPPORT. */
484int
485pstream_verify_name(const char *name)
486{
da327b18 487 const struct pstream_class *class;
26ad129e
BP
488 return pstream_lookup_class(name, &class);
489}
490
f1936eb6
EJ
491/* Returns 1 if the stream or pstream specified by 'name' needs periodic probes
492 * to verify connectivity. For [p]streams which need probes, it can take a
493 * long time to notice the connection has been dropped. Returns 0 if the
494 * stream or pstream does not need probes, and -1 if 'name' is not valid. */
495int
496stream_or_pstream_needs_probes(const char *name)
497{
498 const struct pstream_class *pclass;
499 const struct stream_class *class;
500
501 if (!stream_lookup_class(name, &class)) {
502 return class->needs_probes;
503 } else if (!pstream_lookup_class(name, &pclass)) {
504 return pclass->needs_probes;
505 } else {
506 return -1;
507 }
508}
509
26ad129e
BP
510/* Attempts to start listening for remote stream connections. 'name' is a
511 * connection name in the form "TYPE:ARGS", where TYPE is an passive stream
512 * class's name and ARGS are stream class-specific.
513 *
514 * Returns 0 if successful, otherwise a positive errno value. If successful,
515 * stores a pointer to the new connection in '*pstreamp', otherwise a null
516 * pointer. */
517int
f125905c 518pstream_open(const char *name, struct pstream **pstreamp, uint8_t dscp)
26ad129e 519{
da327b18 520 const struct pstream_class *class;
26ad129e
BP
521 struct pstream *pstream;
522 char *suffix_copy;
523 int error;
524
525 COVERAGE_INC(pstream_open);
526
527 /* Look up the class. */
528 error = pstream_lookup_class(name, &class);
529 if (!class) {
530 goto error;
531 }
532
533 /* Call class's "open" function. */
534 suffix_copy = xstrdup(strchr(name, ':') + 1);
f125905c 535 error = class->listen(name, suffix_copy, &pstream, dscp);
26ad129e
BP
536 free(suffix_copy);
537 if (error) {
538 goto error;
539 }
540
541 /* Success. */
542 *pstreamp = pstream;
543 return 0;
544
545error:
546 *pstreamp = NULL;
547 return error;
548}
549
c34b65c7
BP
550/* Returns the name that was used to open 'pstream'. The caller must not
551 * modify or free the name. */
552const char *
553pstream_get_name(const struct pstream *pstream)
554{
555 return pstream->name;
556}
557
558/* Closes 'pstream'. */
559void
560pstream_close(struct pstream *pstream)
561{
562 if (pstream != NULL) {
563 char *name = pstream->name;
564 (pstream->class->close)(pstream);
565 free(name);
566 }
567}
568
569/* Tries to accept a new connection on 'pstream'. If successful, stores the
570 * new connection in '*new_stream' and returns 0. Otherwise, returns a
571 * positive errno value.
572 *
573 * pstream_accept() will not block waiting for a connection. If no connection
574 * is ready to be accepted, it returns EAGAIN immediately. */
575int
576pstream_accept(struct pstream *pstream, struct stream **new_stream)
577{
578 int retval = (pstream->class->accept)(pstream, new_stream);
579 if (retval) {
580 *new_stream = NULL;
581 } else {
cb22974d
BP
582 ovs_assert((*new_stream)->state != SCS_CONNECTING
583 || (*new_stream)->class->connect);
c34b65c7
BP
584 }
585 return retval;
586}
587
8d76bcca
BP
588/* Tries to accept a new connection on 'pstream'. If successful, stores the
589 * new connection in '*new_stream' and returns 0. Otherwise, returns a
590 * positive errno value.
591 *
592 * pstream_accept_block() blocks until a connection is ready or until an error
593 * occurs. It will not return EAGAIN. */
594int
595pstream_accept_block(struct pstream *pstream, struct stream **new_stream)
596{
597 int error;
598
b302749b 599 fatal_signal_run();
8d76bcca
BP
600 while ((error = pstream_accept(pstream, new_stream)) == EAGAIN) {
601 pstream_wait(pstream);
602 poll_block();
603 }
604 if (error) {
605 *new_stream = NULL;
606 }
607 return error;
608}
609
c34b65c7
BP
610void
611pstream_wait(struct pstream *pstream)
612{
613 (pstream->class->wait)(pstream);
614}
f89b7ce5
IY
615
616int
617pstream_set_dscp(struct pstream *pstream, uint8_t dscp)
618{
619 if (pstream->class->set_dscp) {
620 return pstream->class->set_dscp(pstream, dscp);
621 }
622 return 0;
623}
c34b65c7
BP
624\f
625/* Initializes 'stream' as a new stream named 'name', implemented via 'class'.
626 * The initial connection status, supplied as 'connect_status', is interpreted
627 * as follows:
628 *
629 * - 0: 'stream' is connected. Its 'send' and 'recv' functions may be
630 * called in the normal fashion.
631 *
632 * - EAGAIN: 'stream' is trying to complete a connection. Its 'connect'
633 * function should be called to complete the connection.
634 *
635 * - Other positive errno values indicate that the connection failed with
636 * the specified error.
637 *
638 * After calling this function, stream_close() must be used to destroy
639 * 'stream', otherwise resources will be leaked.
640 *
641 * The caller retains ownership of 'name'. */
642void
da327b18 643stream_init(struct stream *stream, const struct stream_class *class,
c34b65c7
BP
644 int connect_status, const char *name)
645{
c4bed75b 646 memset(stream, 0, sizeof *stream);
c34b65c7
BP
647 stream->class = class;
648 stream->state = (connect_status == EAGAIN ? SCS_CONNECTING
649 : !connect_status ? SCS_CONNECTED
650 : SCS_DISCONNECTED);
651 stream->error = connect_status;
652 stream->name = xstrdup(name);
cb22974d 653 ovs_assert(stream->state != SCS_CONNECTING || class->connect);
c34b65c7
BP
654}
655
656void
4408d18a 657stream_set_remote_ip(struct stream *stream, ovs_be32 ip)
c34b65c7
BP
658{
659 stream->remote_ip = ip;
660}
661
662void
4408d18a 663stream_set_remote_port(struct stream *stream, ovs_be16 port)
c34b65c7
BP
664{
665 stream->remote_port = port;
666}
667
668void
4408d18a 669stream_set_local_ip(struct stream *stream, ovs_be32 ip)
c34b65c7
BP
670{
671 stream->local_ip = ip;
672}
673
674void
4408d18a 675stream_set_local_port(struct stream *stream, ovs_be16 port)
c34b65c7
BP
676{
677 stream->local_port = port;
678}
679
680void
da327b18 681pstream_init(struct pstream *pstream, const struct pstream_class *class,
c34b65c7
BP
682 const char *name)
683{
684 pstream->class = class;
685 pstream->name = xstrdup(name);
686}
f39dc942
BP
687\f
688static int
689count_fields(const char *s_)
690{
691 char *s, *field, *save_ptr;
692 int n = 0;
693
694 save_ptr = NULL;
695 s = xstrdup(s_);
696 for (field = strtok_r(s, ":", &save_ptr); field != NULL;
697 field = strtok_r(NULL, ":", &save_ptr)) {
698 n++;
699 }
700 free(s);
701
702 return n;
703}
704
705/* Like stream_open(), but for tcp streams the port defaults to
706 * 'default_tcp_port' if no port number is given and for SSL streams the port
707 * defaults to 'default_ssl_port' if no port number is given. */
708int
709stream_open_with_default_ports(const char *name_,
710 uint16_t default_tcp_port,
711 uint16_t default_ssl_port,
f125905c
MM
712 struct stream **streamp,
713 uint8_t dscp)
f39dc942
BP
714{
715 char *name;
716 int error;
717
718 if (!strncmp(name_, "tcp:", 4) && count_fields(name_) < 3) {
719 name = xasprintf("%s:%d", name_, default_tcp_port);
720 } else if (!strncmp(name_, "ssl:", 4) && count_fields(name_) < 3) {
721 name = xasprintf("%s:%d", name_, default_ssl_port);
722 } else {
723 name = xstrdup(name_);
724 }
f125905c 725 error = stream_open(name, streamp, dscp);
f39dc942
BP
726 free(name);
727
728 return error;
729}
730
731/* Like pstream_open(), but for ptcp streams the port defaults to
732 * 'default_ptcp_port' if no port number is given and for passive SSL streams
733 * the port defaults to 'default_pssl_port' if no port number is given. */
734int
735pstream_open_with_default_ports(const char *name_,
736 uint16_t default_ptcp_port,
737 uint16_t default_pssl_port,
f125905c
MM
738 struct pstream **pstreamp,
739 uint8_t dscp)
f39dc942
BP
740{
741 char *name;
742 int error;
743
744 if (!strncmp(name_, "ptcp:", 5) && count_fields(name_) < 2) {
745 name = xasprintf("%s%d", name_, default_ptcp_port);
746 } else if (!strncmp(name_, "pssl:", 5) && count_fields(name_) < 2) {
747 name = xasprintf("%s%d", name_, default_pssl_port);
748 } else {
749 name = xstrdup(name_);
750 }
f125905c 751 error = pstream_open(name, pstreamp, dscp);
f39dc942
BP
752 free(name);
753
754 return error;
755}
ac4c900d
AA
756
757/*
758 * This function extracts IP address and port from the target string.
759 *
760 * - On success, function returns true and fills *sin structure with port
761 * and IP address. If port was absent in target string then it will use
762 * corresponding default port value.
763 * - On error, function returns false and *sin contains garbage.
764 */
765bool
766stream_parse_target_with_default_ports(const char *target,
767 uint16_t default_tcp_port,
768 uint16_t default_ssl_port,
769 struct sockaddr_in *sin)
770{
771 return (!strncmp(target, "tcp:", 4)
772 && inet_parse_active(target + 4, default_tcp_port, sin)) ||
773 (!strncmp(target, "ssl:", 4)
774 && inet_parse_active(target + 4, default_ssl_port, sin));
775}
776
1e3c0047
BP
777/* Attempts to guess the content type of a stream whose first few bytes were
778 * the 'size' bytes of 'data'. */
779static enum stream_content_type
c55acc2e 780stream_guess_content(const uint8_t *data, ssize_t size)
1e3c0047
BP
781{
782 if (size >= 2) {
783#define PAIR(A, B) (((A) << 8) | (B))
784 switch (PAIR(data[0], data[1])) {
785 case PAIR(0x16, 0x03): /* Handshake, version 3. */
786 return STREAM_SSL;
787 case PAIR('{', '"'):
788 return STREAM_JSONRPC;
982697a4 789 case PAIR(OFP10_VERSION, 0 /* OFPT_HELLO */):
1e3c0047
BP
790 return STREAM_OPENFLOW;
791 }
792 }
793
794 return STREAM_UNKNOWN;
795}
796
797/* Returns a string represenation of 'type'. */
798static const char *
799stream_content_type_to_string(enum stream_content_type type)
800{
801 switch (type) {
802 case STREAM_UNKNOWN:
803 default:
804 return "unknown";
f39dc942 805
1e3c0047
BP
806 case STREAM_JSONRPC:
807 return "JSON-RPC";
f39dc942 808
1e3c0047
BP
809 case STREAM_OPENFLOW:
810 return "OpenFlow";
811
812 case STREAM_SSL:
813 return "SSL";
814 }
815}
816
817/* Attempts to guess the content type of a stream whose first few bytes were
818 * the 'size' bytes of 'data'. If this is done successfully, and the guessed
819 * content type is other than 'expected_type', then log a message in vlog
820 * module 'module', naming 'stream_name' as the source, explaining what
821 * content was expected and what was actually received. */
822void
c55acc2e 823stream_report_content(const void *data, ssize_t size,
1e3c0047 824 enum stream_content_type expected_type,
480ce8ab 825 struct vlog_module *module, const char *stream_name)
1e3c0047
BP
826{
827 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
828 enum stream_content_type actual_type;
829
830 actual_type = stream_guess_content(data, size);
831 if (actual_type != expected_type && actual_type != STREAM_UNKNOWN) {
832 vlog_rate_limit(module, VLL_WARN, &rl,
833 "%s: received %s data on %s channel",
834 stream_name,
c662c789
BP
835 stream_content_type_to_string(actual_type),
836 stream_content_type_to_string(expected_type));
1e3c0047
BP
837 }
838}