• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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