proto_tcp.c (218193) | proto_tcp.c (218194) |
---|---|
1/*- 2 * Copyright (c) 2009-2010 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Pawel Jakub Dawidek under sponsorship from 6 * the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2009-2010 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Pawel Jakub Dawidek under sponsorship from 6 * the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sbin/hastd/proto_tcp4.c 218193 2011-02-02 15:46:28Z pjd $"); | 31__FBSDID("$FreeBSD: head/sbin/hastd/proto_tcp4.c 218194 2011-02-02 15:53:09Z pjd $"); |
32 33#include <sys/param.h> /* MAXHOSTNAMELEN */ 34 35#include <netinet/in.h> 36#include <netinet/tcp.h> 37 38#include <errno.h> 39#include <fcntl.h> --- 123 unchanged lines hidden (view full) --- 163 if (ip == INADDR_NONE) 164 return (EINVAL); 165 sinp->sin_addr.s_addr = ip; 166 167 return (0); 168} 169 170static int | 32 33#include <sys/param.h> /* MAXHOSTNAMELEN */ 34 35#include <netinet/in.h> 36#include <netinet/tcp.h> 37 38#include <errno.h> 39#include <fcntl.h> --- 123 unchanged lines hidden (view full) --- 163 if (ip == INADDR_NONE) 164 return (EINVAL); 165 sinp->sin_addr.s_addr = ip; 166 167 return (0); 168} 169 170static int |
171tcp4_common_setup(const char *addr, void **ctxp, int side) | 171tcp4_setup_new(const char *addr, int side, void **ctxp) |
172{ 173 struct tcp4_ctx *tctx; 174 int ret, nodelay; 175 | 172{ 173 struct tcp4_ctx *tctx; 174 int ret, nodelay; 175 |
176 PJDLOG_ASSERT(addr != NULL); 177 PJDLOG_ASSERT(side == TCP4_SIDE_CLIENT || 178 side == TCP4_SIDE_SERVER_LISTEN); 179 PJDLOG_ASSERT(ctxp != NULL); 180 |
|
176 tctx = malloc(sizeof(*tctx)); 177 if (tctx == NULL) 178 return (errno); 179 180 /* Parse given address. */ 181 if ((ret = tcp4_addr(addr, &tctx->tc_sin)) != 0) { 182 free(tctx); 183 return (ret); 184 } 185 | 181 tctx = malloc(sizeof(*tctx)); 182 if (tctx == NULL) 183 return (errno); 184 185 /* Parse given address. */ 186 if ((ret = tcp4_addr(addr, &tctx->tc_sin)) != 0) { 187 free(tctx); 188 return (ret); 189 } 190 |
191 PJDLOG_ASSERT(tctx->tc_sin.sin_family != AF_UNSPEC); 192 |
|
186 tctx->tc_fd = socket(AF_INET, SOCK_STREAM, 0); 187 if (tctx->tc_fd == -1) { 188 ret = errno; 189 free(tctx); 190 return (ret); 191 } 192 193 /* Socket settings. */ 194 nodelay = 1; 195 if (setsockopt(tctx->tc_fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, 196 sizeof(nodelay)) == -1) { | 193 tctx->tc_fd = socket(AF_INET, SOCK_STREAM, 0); 194 if (tctx->tc_fd == -1) { 195 ret = errno; 196 free(tctx); 197 return (ret); 198 } 199 200 /* Socket settings. */ 201 nodelay = 1; 202 if (setsockopt(tctx->tc_fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, 203 sizeof(nodelay)) == -1) { |
197 pjdlog_warning("Unable to set TCP_NOELAY on %s", addr); | 204 pjdlog_errno(LOG_WARNING, "Unable to set TCP_NOELAY"); |
198 } 199 200 tctx->tc_side = side; 201 tctx->tc_magic = TCP4_CTX_MAGIC; 202 *ctxp = tctx; 203 204 return (0); 205} 206 207static int | 205 } 206 207 tctx->tc_side = side; 208 tctx->tc_magic = TCP4_CTX_MAGIC; 209 *ctxp = tctx; 210 211 return (0); 212} 213 214static int |
215tcp4_setup_wrap(int fd, int side, void **ctxp) 216{ 217 struct tcp4_ctx *tctx; 218 219 PJDLOG_ASSERT(fd >= 0); 220 PJDLOG_ASSERT(side == TCP4_SIDE_CLIENT || 221 side == TCP4_SIDE_SERVER_WORK); 222 PJDLOG_ASSERT(ctxp != NULL); 223 224 tctx = malloc(sizeof(*tctx)); 225 if (tctx == NULL) 226 return (errno); 227 228 tctx->tc_fd = fd; 229 tctx->tc_sin.sin_family = AF_UNSPEC; 230 tctx->tc_side = side; 231 tctx->tc_magic = TCP4_CTX_MAGIC; 232 *ctxp = tctx; 233 234 return (0); 235} 236 237static int |
|
208tcp4_client(const char *addr, void **ctxp) 209{ 210 | 238tcp4_client(const char *addr, void **ctxp) 239{ 240 |
211 return (tcp4_common_setup(addr, ctxp, TCP4_SIDE_CLIENT)); | 241 return (tcp4_setup_new(addr, TCP4_SIDE_CLIENT, ctxp)); |
212} 213 214static int 215tcp4_connect(void *ctx, int timeout) 216{ 217 struct tcp4_ctx *tctx = ctx; 218 int error, flags; 219 --- 113 unchanged lines hidden (view full) --- 333} 334 335static int 336tcp4_server(const char *addr, void **ctxp) 337{ 338 struct tcp4_ctx *tctx; 339 int ret, val; 340 | 242} 243 244static int 245tcp4_connect(void *ctx, int timeout) 246{ 247 struct tcp4_ctx *tctx = ctx; 248 int error, flags; 249 --- 113 unchanged lines hidden (view full) --- 363} 364 365static int 366tcp4_server(const char *addr, void **ctxp) 367{ 368 struct tcp4_ctx *tctx; 369 int ret, val; 370 |
341 ret = tcp4_common_setup(addr, ctxp, TCP4_SIDE_SERVER_LISTEN); | 371 ret = tcp4_setup_new(addr, TCP4_SIDE_SERVER_LISTEN, ctxp); |
342 if (ret != 0) 343 return (ret); 344 345 tctx = *ctxp; 346 347 val = 1; 348 /* Ignore failure. */ 349 (void)setsockopt(tctx->tc_fd, SOL_SOCKET, SO_REUSEADDR, &val, 350 sizeof(val)); 351 | 372 if (ret != 0) 373 return (ret); 374 375 tctx = *ctxp; 376 377 val = 1; 378 /* Ignore failure. */ 379 (void)setsockopt(tctx->tc_fd, SOL_SOCKET, SO_REUSEADDR, &val, 380 sizeof(val)); 381 |
382 PJDLOG_ASSERT(tctx->tc_sin.sin_family != AF_UNSPEC); 383 |
|
352 if (bind(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin, 353 sizeof(tctx->tc_sin)) < 0) { 354 ret = errno; 355 tcp4_close(tctx); 356 return (ret); 357 } 358 if (listen(tctx->tc_fd, 8) < 0) { 359 ret = errno; --- 11 unchanged lines hidden (view full) --- 371 struct tcp4_ctx *newtctx; 372 socklen_t fromlen; 373 int ret; 374 375 PJDLOG_ASSERT(tctx != NULL); 376 PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC); 377 PJDLOG_ASSERT(tctx->tc_side == TCP4_SIDE_SERVER_LISTEN); 378 PJDLOG_ASSERT(tctx->tc_fd >= 0); | 384 if (bind(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin, 385 sizeof(tctx->tc_sin)) < 0) { 386 ret = errno; 387 tcp4_close(tctx); 388 return (ret); 389 } 390 if (listen(tctx->tc_fd, 8) < 0) { 391 ret = errno; --- 11 unchanged lines hidden (view full) --- 403 struct tcp4_ctx *newtctx; 404 socklen_t fromlen; 405 int ret; 406 407 PJDLOG_ASSERT(tctx != NULL); 408 PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC); 409 PJDLOG_ASSERT(tctx->tc_side == TCP4_SIDE_SERVER_LISTEN); 410 PJDLOG_ASSERT(tctx->tc_fd >= 0); |
411 PJDLOG_ASSERT(tctx->tc_sin.sin_family != AF_UNSPEC); |
|
379 380 newtctx = malloc(sizeof(*newtctx)); 381 if (newtctx == NULL) 382 return (errno); 383 384 fromlen = sizeof(tctx->tc_sin); 385 newtctx->tc_fd = accept(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin, 386 &fromlen); --- 6 unchanged lines hidden (view full) --- 393 newtctx->tc_side = TCP4_SIDE_SERVER_WORK; 394 newtctx->tc_magic = TCP4_CTX_MAGIC; 395 *newctxp = newtctx; 396 397 return (0); 398} 399 400static int | 412 413 newtctx = malloc(sizeof(*newtctx)); 414 if (newtctx == NULL) 415 return (errno); 416 417 fromlen = sizeof(tctx->tc_sin); 418 newtctx->tc_fd = accept(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin, 419 &fromlen); --- 6 unchanged lines hidden (view full) --- 426 newtctx->tc_side = TCP4_SIDE_SERVER_WORK; 427 newtctx->tc_magic = TCP4_CTX_MAGIC; 428 *newctxp = newtctx; 429 430 return (0); 431} 432 433static int |
401tcp4_send(void *ctx, const unsigned char *data, size_t size) | 434tcp4_wrap(int fd, bool client, void **ctxp) |
402{ | 435{ |
436 437 return (tcp4_setup_wrap(fd, 438 client ? TCP4_SIDE_CLIENT : TCP4_SIDE_SERVER_WORK, ctxp)); 439} 440 441static int 442tcp4_send(void *ctx, const unsigned char *data, size_t size, int fd) 443{ |
|
403 struct tcp4_ctx *tctx = ctx; 404 405 PJDLOG_ASSERT(tctx != NULL); 406 PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC); 407 PJDLOG_ASSERT(tctx->tc_fd >= 0); | 444 struct tcp4_ctx *tctx = ctx; 445 446 PJDLOG_ASSERT(tctx != NULL); 447 PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC); 448 PJDLOG_ASSERT(tctx->tc_fd >= 0); |
449 PJDLOG_ASSERT(fd == -1); |
|
408 | 450 |
409 return (proto_common_send(tctx->tc_fd, data, size)); | 451 return (proto_common_send(tctx->tc_fd, data, size, -1)); |
410} 411 412static int | 452} 453 454static int |
413tcp4_recv(void *ctx, unsigned char *data, size_t size) | 455tcp4_recv(void *ctx, unsigned char *data, size_t size, int *fdp) |
414{ 415 struct tcp4_ctx *tctx = ctx; 416 417 PJDLOG_ASSERT(tctx != NULL); 418 PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC); 419 PJDLOG_ASSERT(tctx->tc_fd >= 0); | 456{ 457 struct tcp4_ctx *tctx = ctx; 458 459 PJDLOG_ASSERT(tctx != NULL); 460 PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC); 461 PJDLOG_ASSERT(tctx->tc_fd >= 0); |
462 PJDLOG_ASSERT(fdp == NULL); |
|
420 | 463 |
421 return (proto_common_recv(tctx->tc_fd, data, size)); | 464 return (proto_common_recv(tctx->tc_fd, data, size, NULL)); |
422} 423 424static int 425tcp4_descriptor(const void *ctx) 426{ 427 const struct tcp4_ctx *tctx = ctx; 428 429 PJDLOG_ASSERT(tctx != NULL); --- 93 unchanged lines hidden (view full) --- 523 524static struct hast_proto tcp4_proto = { 525 .hp_name = "tcp4", 526 .hp_client = tcp4_client, 527 .hp_connect = tcp4_connect, 528 .hp_connect_wait = tcp4_connect_wait, 529 .hp_server = tcp4_server, 530 .hp_accept = tcp4_accept, | 465} 466 467static int 468tcp4_descriptor(const void *ctx) 469{ 470 const struct tcp4_ctx *tctx = ctx; 471 472 PJDLOG_ASSERT(tctx != NULL); --- 93 unchanged lines hidden (view full) --- 566 567static struct hast_proto tcp4_proto = { 568 .hp_name = "tcp4", 569 .hp_client = tcp4_client, 570 .hp_connect = tcp4_connect, 571 .hp_connect_wait = tcp4_connect_wait, 572 .hp_server = tcp4_server, 573 .hp_accept = tcp4_accept, |
574 .hp_wrap = tcp4_wrap, |
|
531 .hp_send = tcp4_send, 532 .hp_recv = tcp4_recv, 533 .hp_descriptor = tcp4_descriptor, 534 .hp_address_match = tcp4_address_match, 535 .hp_local_address = tcp4_local_address, 536 .hp_remote_address = tcp4_remote_address, 537 .hp_close = tcp4_close 538}; 539 540static __constructor void 541tcp4_ctor(void) 542{ 543 544 proto_register(&tcp4_proto, true); 545} | 575 .hp_send = tcp4_send, 576 .hp_recv = tcp4_recv, 577 .hp_descriptor = tcp4_descriptor, 578 .hp_address_match = tcp4_address_match, 579 .hp_local_address = tcp4_local_address, 580 .hp_remote_address = tcp4_remote_address, 581 .hp_close = tcp4_close 582}; 583 584static __constructor void 585tcp4_ctor(void) 586{ 587 588 proto_register(&tcp4_proto, true); 589} |