Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
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.h"
19 : : #include <errno.h>
20 : : #include <inttypes.h>
21 : : #include <netdb.h>
22 : : #include <poll.h>
23 : : #include <sys/socket.h>
24 : : #include <sys/types.h>
25 : : #include <sys/un.h>
26 : : #include <stdlib.h>
27 : : #include <string.h>
28 : : #include <unistd.h>
29 : : #include "packets.h"
30 : : #include "poll-loop.h"
31 : : #include "socket-util.h"
32 : : #include "dirs.h"
33 : : #include "util.h"
34 : : #include "stream-provider.h"
35 : : #include "stream-fd.h"
36 : : #include "openvswitch/vlog.h"
37 : :
38 : 53956 : VLOG_DEFINE_THIS_MODULE(stream_unix);
39 : :
40 : : /* Active UNIX socket. */
41 : :
42 : : static int
43 : 25757 : unix_open(const char *name, char *suffix, struct stream **streamp,
44 : : uint8_t dscp OVS_UNUSED)
45 : : {
46 : : char *connect_path;
47 : : int fd;
48 : :
49 : 25757 : connect_path = abs_file_name(ovs_rundir(), suffix);
50 : 25757 : fd = make_unix_socket(SOCK_STREAM, true, NULL, connect_path);
51 : :
52 [ + + ]: 25757 : if (fd < 0) {
53 [ + + ]: 3410 : VLOG_DBG("%s: connection failed (%s)",
54 : : connect_path, ovs_strerror(-fd));
55 : 3410 : free(connect_path);
56 : 3410 : return -fd;
57 : : }
58 : :
59 : 22347 : free(connect_path);
60 : 22347 : return new_fd_stream(name, fd, check_connection_completion(fd),
61 : : AF_UNIX, streamp);
62 : : }
63 : :
64 : : const struct stream_class unix_stream_class = {
65 : : "unix", /* name */
66 : : false, /* needs_probes */
67 : : unix_open, /* open */
68 : : NULL, /* close */
69 : : NULL, /* connect */
70 : : NULL, /* recv */
71 : : NULL, /* send */
72 : : NULL, /* run */
73 : : NULL, /* run_wait */
74 : : NULL, /* wait */
75 : : };
76 : :
77 : : /* Passive UNIX socket. */
78 : :
79 : : static int punix_accept(int fd, const struct sockaddr_storage *ss,
80 : : size_t ss_len, struct stream **streamp);
81 : :
82 : : static int
83 : 4914 : punix_open(const char *name OVS_UNUSED, char *suffix,
84 : : struct pstream **pstreamp, uint8_t dscp OVS_UNUSED)
85 : : {
86 : : char *bind_path;
87 : : int fd, error;
88 : :
89 : 4914 : bind_path = abs_file_name(ovs_rundir(), suffix);
90 : 4914 : fd = make_unix_socket(SOCK_STREAM, true, bind_path, NULL);
91 [ + + ]: 4914 : if (fd < 0) {
92 [ + - ]: 2 : VLOG_ERR("%s: binding failed: %s", bind_path, ovs_strerror(errno));
93 : 2 : free(bind_path);
94 : 2 : return errno;
95 : : }
96 : :
97 [ - + ]: 4912 : if (listen(fd, 64) < 0) {
98 : 0 : error = errno;
99 [ # # ]: 0 : VLOG_ERR("%s: listen: %s", name, ovs_strerror(error));
100 : 0 : close(fd);
101 : 0 : free(bind_path);
102 : 0 : return error;
103 : : }
104 : :
105 : 4912 : return new_fd_pstream(name, fd, punix_accept, bind_path, pstreamp);
106 : : }
107 : :
108 : : static int
109 : 21868 : punix_accept(int fd, const struct sockaddr_storage *ss, size_t ss_len,
110 : : struct stream **streamp)
111 : : {
112 : 21868 : const struct sockaddr_un *sun = (const struct sockaddr_un *) ss;
113 : 21868 : int name_len = get_unix_name_len(sun, ss_len);
114 : : char name[128];
115 : :
116 [ - + ]: 21868 : if (name_len > 0) {
117 : 0 : snprintf(name, sizeof name, "unix:%.*s", name_len, sun->sun_path);
118 : : } else {
119 : 21868 : strcpy(name, "unix");
120 : : }
121 : 21868 : return new_fd_stream(name, fd, 0, AF_UNIX, streamp);
122 : : }
123 : :
124 : : const struct pstream_class punix_pstream_class = {
125 : : "punix",
126 : : false,
127 : : punix_open,
128 : : NULL,
129 : : NULL,
130 : : NULL,
131 : : };
132 : :
|