OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/udp/udp_socket_libevent.h" | 5 #include "net/udp/udp_socket_libevent.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <netdb.h> | 9 #include <netdb.h> |
10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 CreateNetLogUDPDataTranferCallback( | 356 CreateNetLogUDPDataTranferCallback( |
357 result, bytes, | 357 result, bytes, |
358 is_address_valid ? &address : NULL)); | 358 is_address_valid ? &address : NULL)); |
359 } | 359 } |
360 | 360 |
361 base::StatsCounter read_bytes("udp.read_bytes"); | 361 base::StatsCounter read_bytes("udp.read_bytes"); |
362 read_bytes.Add(result); | 362 read_bytes.Add(result); |
363 } | 363 } |
364 | 364 |
365 int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) { | 365 int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) { |
366 socket_ = socket(address.GetSockAddrFamily(), SOCK_DGRAM, 0); | 366 sock_addr_family_ = address.GetSockAddrFamily(); |
| 367 socket_ = socket(sock_addr_family_, SOCK_DGRAM, 0); |
367 if (socket_ == kInvalidSocket) | 368 if (socket_ == kInvalidSocket) |
368 return MapSystemError(errno); | 369 return MapSystemError(errno); |
369 if (SetNonBlocking(socket_)) { | 370 if (SetNonBlocking(socket_)) { |
370 const int err = MapSystemError(errno); | 371 const int err = MapSystemError(errno); |
371 Close(); | 372 Close(); |
372 return err; | 373 return err; |
373 } | 374 } |
374 return OK; | 375 return OK; |
375 } | 376 } |
376 | 377 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 IPAddressNumber ip(address.address().size()); | 503 IPAddressNumber ip(address.address().size()); |
503 | 504 |
504 for (int i = 0; i < kBindRetries; ++i) { | 505 for (int i = 0; i < kBindRetries; ++i) { |
505 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); | 506 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); |
506 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 507 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
507 return rv; | 508 return rv; |
508 } | 509 } |
509 return DoBind(IPEndPoint(ip, 0)); | 510 return DoBind(IPEndPoint(ip, 0)); |
510 } | 511 } |
511 | 512 |
| 513 int UDPSocketLibevent::JoinGroup( |
| 514 const net::IPAddressNumber& group_address) const { |
| 515 DCHECK(CalledOnValidThread()); |
| 516 DCHECK(is_connected()); |
| 517 |
| 518 int rv = -1; |
| 519 switch(group_address.size()) { |
| 520 case kIPv4AddressSize: { |
| 521 if (sock_addr_family_ != AF_INET) { |
| 522 return ERR_ADDRESS_INVALID; |
| 523 } |
| 524 ip_mreq mreq; |
| 525 memset(&mreq, 0, sizeof(mreq)); |
| 526 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); |
| 527 rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, |
| 528 &mreq, sizeof(mreq)); |
| 529 break; |
| 530 } |
| 531 case kIPv6AddressSize: { |
| 532 if (sock_addr_family_ != AF_INET6) { |
| 533 return ERR_ADDRESS_INVALID; |
| 534 } |
| 535 ipv6_mreq mreq; |
| 536 memset(&mreq, 0, sizeof(mreq)); |
| 537 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); |
| 538 rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_JOIN_GROUP, |
| 539 &mreq, sizeof(mreq)); |
| 540 break; |
| 541 } |
| 542 } |
| 543 |
| 544 return MapSystemError(rv); |
| 545 } |
| 546 |
| 547 int UDPSocketLibevent::LeaveGroup( |
| 548 const net::IPAddressNumber& group_address) const { |
| 549 DCHECK(CalledOnValidThread()); |
| 550 DCHECK(is_connected()); |
| 551 |
| 552 int rv = -1; |
| 553 switch(group_address.size()) { |
| 554 case kIPv4AddressSize: { |
| 555 if (sock_addr_family_ != AF_INET) { |
| 556 return ERR_ADDRESS_INVALID; |
| 557 } |
| 558 ip_mreq mreq; |
| 559 memset(&mreq, 0, sizeof(mreq)); |
| 560 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); |
| 561 rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP, |
| 562 &mreq, sizeof(mreq)); |
| 563 break; |
| 564 } |
| 565 case kIPv6AddressSize: { |
| 566 if (sock_addr_family_ != AF_INET6) { |
| 567 return ERR_ADDRESS_INVALID; |
| 568 } |
| 569 ipv6_mreq mreq; |
| 570 memset(&mreq, 0, sizeof(mreq)); |
| 571 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); |
| 572 rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_LEAVE_GROUP, |
| 573 &mreq, sizeof(mreq)); |
| 574 break; |
| 575 } |
| 576 } |
| 577 |
| 578 return MapSystemError(rv); |
| 579 } |
| 580 |
| 581 int UDPSocketLibevent::SetMulticastTimeToLive(int timeToLive) { |
| 582 DCHECK(CalledOnValidThread()); |
| 583 DCHECK(is_connected()); |
| 584 |
| 585 uint8 ttl = timeToLive; |
| 586 int ip_family = sock_addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
| 587 return MapSystemError(setsockopt(socket_, |
| 588 ip_family, |
| 589 IP_MULTICAST_TTL, |
| 590 &ttl, sizeof(ttl))); |
| 591 } |
| 592 |
| 593 int UDPSocketLibevent::SetMulticastLoopbackMode(bool loopback) { |
| 594 DCHECK(CalledOnValidThread()); |
| 595 DCHECK(is_connected()); |
| 596 |
| 597 uint8 loop = loopback; |
| 598 int ip_family = sock_addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
| 599 return MapSystemError(setsockopt(socket_, |
| 600 ip_family, |
| 601 IP_MULTICAST_LOOP, |
| 602 &loop, sizeof(loop))); |
| 603 } |
512 } // namespace net | 604 } // namespace net |
OLD | NEW |