1use rdma_sys::*;
15use std::ptr::null_mut;
16
17static SERVER: &str = "0.0.0.0\0";
18static PORT: &str = "7471\0";
19
20fn run() -> i32 {
21 let mut send_msg = vec![1_u8; 16];
22 let mut recv_msg = vec![0_u8; 16];
23 let mut hints = unsafe { std::mem::zeroed::<rdma_addrinfo>() };
24 let mut res: *mut rdma_addrinfo = null_mut();
25 hints.ai_flags = RAI_PASSIVE.try_into().unwrap();
26 hints.ai_port_space = rdma_port_space::RDMA_PS_TCP.try_into().unwrap();
27 let mut ret = unsafe {
28 rdma_getaddrinfo(
29 SERVER.as_ptr().cast(),
30 PORT.as_ptr().cast(),
31 &hints,
32 &mut res,
33 )
34 };
35
36 if ret != 0 {
37 println!("rdma_getaddrinfo");
38 return ret;
39 }
40
41 let mut listen_id = null_mut();
42 let mut id = null_mut();
43
44 let mut init_attr = unsafe { std::mem::zeroed::<ibv_qp_init_attr>() };
45 init_attr.cap.max_send_wr = 1;
46 init_attr.cap.max_recv_wr = 1;
47 init_attr.cap.max_send_sge = 1;
48 init_attr.cap.max_recv_sge = 1;
49 init_attr.cap.max_inline_data = 16;
50 init_attr.sq_sig_all = 1;
51 ret = unsafe { rdma_create_ep(&mut listen_id, res, null_mut(), &mut init_attr) };
52 if ret != 0 {
54 println!("rdma_create_ep");
55 unsafe {
56 rdma_freeaddrinfo(res);
57 }
58 return ret;
59 }
60 ret = unsafe { rdma_listen(listen_id, 0) };
61 if ret != 0 {
62 println!("rdma_listen");
63 unsafe {
64 rdma_destroy_ep(listen_id);
65 }
66 return ret;
67 }
68
69 ret = unsafe { rdma_get_request(listen_id, &mut id) };
70 if ret != 0 {
71 println!("rdma_get_request");
72 unsafe {
73 rdma_destroy_ep(listen_id);
74 }
75 return ret;
76 }
77
78 let mut qp_attr = unsafe { std::mem::zeroed::<ibv_qp_attr>() };
79 ret = unsafe {
80 ibv_query_qp(
81 (*id).qp,
82 &mut qp_attr,
83 ibv_qp_attr_mask::IBV_QP_CAP.0.try_into().unwrap(),
84 &mut init_attr,
85 )
86 };
87
88 if ret != 0 {
89 println!("ibv_query_qp");
90 unsafe {
91 rdma_destroy_ep(id);
92 }
93 return ret;
94 }
95
96 let mut send_flags = 0_u32;
97 if init_attr.cap.max_inline_data >= 16 {
98 send_flags = ibv_send_flags::IBV_SEND_INLINE.0;
99 } else {
100 println!("rdma_server: device doesn't support IBV_SEND_INLINE, using sge sends");
101 }
102
103 let recv_mr = unsafe { rdma_reg_msgs(id, recv_msg.as_mut_ptr().cast(), 16) };
104 if recv_mr.is_null() {
105 ret = -1;
106 println!("rdma_reg_msgs for recv_msg");
107 unsafe {
108 rdma_dereg_mr(recv_mr);
109 }
110 return ret;
111 }
112
113 let mut send_mr = null_mut();
114 if (send_flags & ibv_send_flags::IBV_SEND_INLINE.0) == 0 {
115 send_mr = unsafe { rdma_reg_msgs(id, send_msg.as_mut_ptr().cast(), 16) };
116 if send_mr.is_null() {
117 ret = -1;
118 println!("rdma_reg_msgs for send_msg");
119 unsafe {
120 rdma_dereg_mr(recv_mr);
121 }
122 return ret;
123 }
124 }
125 ret = unsafe { rdma_post_recv(id, null_mut(), recv_msg.as_mut_ptr().cast(), 16, recv_mr) };
126
127 if ret != 0 {
128 println!("rdma_post_recv");
129 unsafe {
130 rdma_dereg_mr(recv_mr);
131 }
132 return ret;
133 }
134
135 ret = unsafe { rdma_accept(id, null_mut()) };
136 if ret != 0 {
137 println!("rdma_accept");
138 if (send_flags & ibv_send_flags::IBV_SEND_INLINE.0) == 0 {
139 unsafe { rdma_dereg_mr(send_mr) };
140 }
141 return ret;
142 }
143
144 let mut wc = unsafe { std::mem::zeroed::<ibv_wc>() };
145 while ret == 0 {
146 ret = unsafe { rdma_get_recv_comp(id, &mut wc) };
147 }
148 if ret < 0 {
149 println!("rdma_get_recv_comp");
150 unsafe {
151 rdma_disconnect(id);
152 }
153 return ret;
154 }
155 println!("rdma_server: recv msg : {:?}", recv_msg);
156 ret = unsafe {
157 rdma_post_send(
158 id,
159 null_mut(),
160 send_msg.as_mut_ptr().cast(),
161 16,
162 send_mr,
163 send_flags.try_into().unwrap(),
164 )
165 };
166 if ret != 0 {
167 println!("rdma_post_send");
168 unsafe {
169 rdma_disconnect(id);
170 }
171 return ret;
172 }
173
174 while ret == 0 {
175 ret = unsafe { rdma_get_send_comp(id, &mut wc) };
176 }
177 if ret < 0 {
178 println!("rdma_get_send_comp");
179 } else {
180 ret = 0;
181 }
182 ret
183}
184
185fn main() {
186 println!("rdma_server: start");
187 let ret = run();
188 if ret != 0 {
189 println!(
190 "rdma_server: ret error {:?}",
191 std::io::Error::from_raw_os_error(-ret)
192 );
193 if ret == -1 {
194 println!(
195 "rdma_server: last os error {:?}",
196 std::io::Error::last_os_error()
197 );
198 }
199 }
200 println!("rdma_server: end");
201}