]>
Commit | Line | Data |
---|---|---|
c34b65c7 | 1 | /* |
67a4917b | 2 | * Copyright (c) 2008, 2009, 2010 Nicira Networks. |
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.h" | |
19 | #include <assert.h> | |
20 | #include <errno.h> | |
21 | #include <inttypes.h> | |
22 | #include <netdb.h> | |
23 | #include <poll.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 "util.h" | |
33 | #include "stream-provider.h" | |
34 | #include "stream-fd.h" | |
35 | ||
36 | #include "vlog.h" | |
37 | #define THIS_MODULE VLM_stream_unix | |
38 | ||
39 | /* Active UNIX socket. */ | |
40 | ||
41 | /* Number of unix sockets created so far, to ensure binding path uniqueness. */ | |
42 | static int n_unix_sockets; | |
43 | ||
44 | static int | |
45 | unix_open(const char *name, char *suffix, struct stream **streamp) | |
46 | { | |
47 | const char *connect_path = suffix; | |
48 | char *bind_path; | |
49 | int fd; | |
50 | ||
51 | bind_path = xasprintf("/tmp/stream-unix.%ld.%d", | |
52 | (long int) getpid(), n_unix_sockets++); | |
53 | fd = make_unix_socket(SOCK_STREAM, true, false, bind_path, connect_path); | |
54 | if (fd < 0) { | |
55 | VLOG_ERR("%s: connection to %s failed: %s", | |
56 | bind_path, connect_path, strerror(-fd)); | |
57 | free(bind_path); | |
58 | return -fd; | |
59 | } | |
60 | ||
61 | return new_fd_stream(name, fd, check_connection_completion(fd), | |
62 | bind_path, streamp); | |
63 | } | |
64 | ||
65 | struct stream_class unix_stream_class = { | |
66 | "unix", /* name */ | |
67 | unix_open, /* open */ | |
68 | NULL, /* close */ | |
69 | NULL, /* connect */ | |
70 | NULL, /* recv */ | |
71 | NULL, /* send */ | |
539e96f6 BP |
72 | NULL, /* run */ |
73 | NULL, /* run_wait */ | |
c34b65c7 BP |
74 | NULL, /* wait */ |
75 | }; | |
76 | \f | |
77 | /* Passive UNIX socket. */ | |
78 | ||
79 | static int punix_accept(int fd, const struct sockaddr *sa, size_t sa_len, | |
80 | struct stream **streamp); | |
81 | ||
82 | static int | |
c69ee87c BP |
83 | punix_open(const char *name OVS_UNUSED, char *suffix, |
84 | struct pstream **pstreamp) | |
c34b65c7 BP |
85 | { |
86 | int fd, error; | |
87 | ||
88 | fd = make_unix_socket(SOCK_STREAM, true, true, suffix, NULL); | |
89 | if (fd < 0) { | |
90 | VLOG_ERR("%s: binding failed: %s", suffix, strerror(errno)); | |
91 | return errno; | |
92 | } | |
93 | ||
c34b65c7 BP |
94 | if (listen(fd, 10) < 0) { |
95 | error = errno; | |
96 | VLOG_ERR("%s: listen: %s", name, strerror(error)); | |
97 | close(fd); | |
98 | return error; | |
99 | } | |
100 | ||
101 | return new_fd_pstream("punix", fd, punix_accept, | |
102 | xstrdup(suffix), pstreamp); | |
103 | } | |
104 | ||
105 | static int | |
106 | punix_accept(int fd, const struct sockaddr *sa, size_t sa_len, | |
107 | struct stream **streamp) | |
108 | { | |
109 | const struct sockaddr_un *sun = (const struct sockaddr_un *) sa; | |
110 | int name_len = get_unix_name_len(sa_len); | |
111 | char name[128]; | |
112 | ||
113 | if (name_len > 0) { | |
114 | snprintf(name, sizeof name, "unix:%.*s", name_len, sun->sun_path); | |
115 | } else { | |
116 | strcpy(name, "unix"); | |
117 | } | |
118 | return new_fd_stream(name, fd, 0, NULL, streamp); | |
119 | } | |
120 | ||
121 | struct pstream_class punix_pstream_class = { | |
122 | "punix", | |
123 | punix_open, | |
124 | NULL, | |
125 | NULL, | |
126 | NULL | |
127 | }; | |
128 |