1 // Copyright 2018 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 mod msg_on_socket;
6
7 use std::io::Result;
8 use std::marker::PhantomData;
9 use std::ops::Deref;
10 use std::os::unix::io::{AsRawFd, RawFd};
11
12 use sys_util::{handle_eintr, net::UnixSeqpacket, Error as SysError, ScmSocket};
13
14 pub use crate::msg_on_socket::*;
15 pub use msg_on_socket_derive::*;
16
17 /// Create a pair of socket. Request is send in one direction while response is in the other
18 /// direction.
pair<Request: MsgOnSocket, Response: MsgOnSocket>( ) -> Result<(MsgSocket<Request, Response>, MsgSocket<Response, Request>)>19 pub fn pair<Request: MsgOnSocket, Response: MsgOnSocket>(
20 ) -> Result<(MsgSocket<Request, Response>, MsgSocket<Response, Request>)> {
21 let (sock1, sock2) = UnixSeqpacket::pair()?;
22 let requester = MsgSocket {
23 sock: sock1,
24 _i: PhantomData,
25 _o: PhantomData,
26 };
27 let responder = MsgSocket {
28 sock: sock2,
29 _i: PhantomData,
30 _o: PhantomData,
31 };
32 Ok((requester, responder))
33 }
34
35 /// Bidirection sock that support both send and recv.
36 pub struct MsgSocket<I: MsgOnSocket, O: MsgOnSocket> {
37 sock: UnixSeqpacket,
38 _i: PhantomData<I>,
39 _o: PhantomData<O>,
40 }
41
42 impl<I: MsgOnSocket, O: MsgOnSocket> MsgSocket<I, O> {
43 // Create a new MsgSocket.
new(s: UnixSeqpacket) -> MsgSocket<I, O>44 pub fn new(s: UnixSeqpacket) -> MsgSocket<I, O> {
45 MsgSocket {
46 sock: s,
47 _i: PhantomData,
48 _o: PhantomData,
49 }
50 }
51 }
52
53 impl<I: MsgOnSocket, O: MsgOnSocket> Deref for MsgSocket<I, O> {
54 type Target = UnixSeqpacket;
deref(&self) -> &Self::Target55 fn deref(&self) -> &Self::Target {
56 &self.sock
57 }
58 }
59
60 /// One direction socket that only supports sending.
61 pub struct Sender<M: MsgOnSocket> {
62 sock: UnixSeqpacket,
63 _m: PhantomData<M>,
64 }
65
66 impl<M: MsgOnSocket> Sender<M> {
67 /// Create a new sender sock.
new(s: UnixSeqpacket) -> Sender<M>68 pub fn new(s: UnixSeqpacket) -> Sender<M> {
69 Sender {
70 sock: s,
71 _m: PhantomData,
72 }
73 }
74 }
75
76 /// One direction socket that only supports receiving.
77 pub struct Receiver<M: MsgOnSocket> {
78 sock: UnixSeqpacket,
79 _m: PhantomData<M>,
80 }
81
82 impl<M: MsgOnSocket> Receiver<M> {
83 /// Create a new receiver sock.
new(s: UnixSeqpacket) -> Receiver<M>84 pub fn new(s: UnixSeqpacket) -> Receiver<M> {
85 Receiver {
86 sock: s,
87 _m: PhantomData,
88 }
89 }
90 }
91
92 impl<I: MsgOnSocket, O: MsgOnSocket> AsRef<UnixSeqpacket> for MsgSocket<I, O> {
as_ref(&self) -> &UnixSeqpacket93 fn as_ref(&self) -> &UnixSeqpacket {
94 &self.sock
95 }
96 }
97
98 impl<I: MsgOnSocket, O: MsgOnSocket> AsRawFd for MsgSocket<I, O> {
as_raw_fd(&self) -> RawFd99 fn as_raw_fd(&self) -> RawFd {
100 self.sock.as_raw_fd()
101 }
102 }
103
104 impl<M: MsgOnSocket> AsRef<UnixSeqpacket> for Sender<M> {
as_ref(&self) -> &UnixSeqpacket105 fn as_ref(&self) -> &UnixSeqpacket {
106 &self.sock
107 }
108 }
109
110 impl<M: MsgOnSocket> AsRawFd for Sender<M> {
as_raw_fd(&self) -> RawFd111 fn as_raw_fd(&self) -> RawFd {
112 self.sock.as_raw_fd()
113 }
114 }
115
116 impl<M: MsgOnSocket> AsRef<UnixSeqpacket> for Receiver<M> {
as_ref(&self) -> &UnixSeqpacket117 fn as_ref(&self) -> &UnixSeqpacket {
118 &self.sock
119 }
120 }
121
122 impl<M: MsgOnSocket> AsRawFd for Receiver<M> {
as_raw_fd(&self) -> RawFd123 fn as_raw_fd(&self) -> RawFd {
124 self.sock.as_raw_fd()
125 }
126 }
127
128 /// Types that could send a message.
129 pub trait MsgSender<M: MsgOnSocket>: AsRef<UnixSeqpacket> {
send(&self, msg: &M) -> MsgResult<()>130 fn send(&self, msg: &M) -> MsgResult<()> {
131 let msg_size = M::msg_size();
132 let fd_size = M::max_fd_count();
133 let mut msg_buffer: Vec<u8> = vec![0; msg_size];
134 let mut fd_buffer: Vec<RawFd> = vec![0; fd_size];
135
136 let fd_size = msg.write_to_buffer(&mut msg_buffer, &mut fd_buffer)?;
137 let sock: &UnixSeqpacket = self.as_ref();
138 if fd_size == 0 {
139 handle_eintr!(sock.send(&msg_buffer))
140 .map_err(|e| MsgError::Send(SysError::new(e.raw_os_error().unwrap_or(0))))?;
141 } else {
142 sock.send_with_fds(&msg_buffer[..], &fd_buffer[0..fd_size])
143 .map_err(MsgError::Send)?;
144 }
145 Ok(())
146 }
147 }
148
149 /// Types that could receive a message.
150 pub trait MsgReceiver<M: MsgOnSocket>: AsRef<UnixSeqpacket> {
recv(&self) -> MsgResult<M>151 fn recv(&self) -> MsgResult<M> {
152 let msg_size = M::msg_size();
153 let fd_size = M::max_fd_count();
154 let mut msg_buffer: Vec<u8> = vec![0; msg_size];
155 let mut fd_buffer: Vec<RawFd> = vec![0; fd_size];
156
157 let sock: &UnixSeqpacket = self.as_ref();
158
159 let (recv_msg_size, recv_fd_size) = {
160 if fd_size == 0 {
161 let size = sock
162 .recv(&mut msg_buffer)
163 .map_err(|e| MsgError::Recv(SysError::new(e.raw_os_error().unwrap_or(0))))?;
164 (size, 0)
165 } else {
166 sock.recv_with_fds(&mut msg_buffer, &mut fd_buffer)
167 .map_err(MsgError::Recv)?
168 }
169 };
170 if msg_size != recv_msg_size {
171 return Err(MsgError::BadRecvSize {
172 expected: msg_size,
173 actual: recv_msg_size,
174 });
175 }
176 // Safe because fd buffer is read from socket.
177 let (v, read_fd_size) = unsafe {
178 M::read_from_buffer(&msg_buffer[0..recv_msg_size], &fd_buffer[0..recv_fd_size])?
179 };
180 if recv_fd_size != read_fd_size {
181 return Err(MsgError::NotExpectFd);
182 }
183 Ok(v)
184 }
185 }
186
187 impl<I: MsgOnSocket, O: MsgOnSocket> MsgSender<I> for MsgSocket<I, O> {}
188 impl<I: MsgOnSocket, O: MsgOnSocket> MsgReceiver<O> for MsgSocket<I, O> {}
189
190 impl<M: MsgOnSocket> MsgSender<M> for Sender<M> {}
191 impl<M: MsgOnSocket> MsgReceiver<M> for Receiver<M> {}
192