| 172 | } |
| 173 | |
| 174 | int t_create_socket_pair(int fd[2], bool stream) |
| 175 | { |
| 176 | int ret; |
| 177 | int type = stream ? SOCK_STREAM : SOCK_DGRAM; |
| 178 | int val; |
| 179 | struct sockaddr_in serv_addr; |
| 180 | struct sockaddr *paddr; |
| 181 | socklen_t paddrlen; |
| 182 | |
| 183 | type |= SOCK_CLOEXEC; |
| 184 | fd[0] = socket(AF_INET, type, 0); |
| 185 | if (fd[0] < 0) |
| 186 | return errno; |
| 187 | fd[1] = socket(AF_INET, type, 0); |
| 188 | if (fd[1] < 0) { |
| 189 | ret = errno; |
| 190 | close(fd[0]); |
| 191 | return ret; |
| 192 | } |
| 193 | |
| 194 | val = 1; |
| 195 | if (setsockopt(fd[0], SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))) |
| 196 | goto errno_cleanup; |
| 197 | |
| 198 | memset(&serv_addr, 0, sizeof(serv_addr)); |
| 199 | serv_addr.sin_family = AF_INET; |
| 200 | serv_addr.sin_port = 0; |
| 201 | inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr); |
| 202 | |
| 203 | paddr = (struct sockaddr *)&serv_addr; |
| 204 | paddrlen = sizeof(serv_addr); |
| 205 | |
| 206 | if (bind(fd[0], paddr, paddrlen)) { |
| 207 | fprintf(stderr, "bind failed\n"); |
| 208 | goto errno_cleanup; |
| 209 | } |
| 210 | |
| 211 | if (stream && listen(fd[0], 16)) { |
| 212 | fprintf(stderr, "listen failed\n"); |
| 213 | goto errno_cleanup; |
| 214 | } |
| 215 | |
| 216 | if (getsockname(fd[0], (struct sockaddr *)&serv_addr, |
| 217 | (socklen_t *)&paddrlen)) { |
| 218 | fprintf(stderr, "getsockname failed\n"); |
| 219 | goto errno_cleanup; |
| 220 | } |
| 221 | inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr); |
| 222 | |
| 223 | if (connect(fd[1], (struct sockaddr *)&serv_addr, paddrlen)) { |
| 224 | fprintf(stderr, "connect failed\n"); |
| 225 | goto errno_cleanup; |
| 226 | } |
| 227 | |
| 228 | if (!stream) { |
| 229 | /* connect the other udp side */ |
| 230 | if (getsockname(fd[1], (struct sockaddr *)&serv_addr, |
| 231 | (socklen_t *)&paddrlen)) { |
no outgoing calls