blob: bb7ddae5e686b30ecf637affea747a099922f348 [file] [log] [blame]
Paul Stewartac1328e2012-07-20 11:55:40 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkov633ac6f2011-07-08 13:56:13 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Paul Stewartf65320c2011-10-13 14:34:52 -07005#include "shill/sockets.h"
6
7#include <errno.h>
8#include <fcntl.h>
9#include <net/if.h>
10#include <stdio.h>
Darin Petkove0a312e2011-07-20 13:45:28 -070011#include <sys/ioctl.h>
Darin Petkov633ac6f2011-07-08 13:56:13 -070012#include <sys/socket.h>
13#include <unistd.h>
14
Paul Stewart5ad16062013-02-21 18:10:48 -080015#include <base/posix/eintr_wrapper.h>
Gary Morain41780232012-07-31 15:08:31 -070016
Christopher Wileyb691efd2012-08-09 13:51:51 -070017#include "shill/logging.h"
Darin Petkov633ac6f2011-07-08 13:56:13 -070018
19namespace shill {
20
Wade Guthriefa2100e2013-05-15 10:11:22 -070021Sockets::Sockets() {}
22
Darin Petkov633ac6f2011-07-08 13:56:13 -070023Sockets::~Sockets() {}
24
Gary Morain41780232012-07-31 15:08:31 -070025// Some system calls can be interrupted and return EINTR, but will succeed on
26// retry. The HANDLE_EINTR macro retries a call if it returns EINTR. For a
27// list of system calls that can return EINTR, see 'man 7 signal' under the
28// heading "Interruption of System Calls and Library Functions by Signal
29// Handlers".
30
Wade Guthrie9f62cd12013-05-15 10:40:42 -070031int Sockets::Accept(int sockfd,
32 struct sockaddr *addr,
33 socklen_t *addrlen) const {
Gary Morain41780232012-07-31 15:08:31 -070034 return HANDLE_EINTR(accept(sockfd, addr, addrlen));
Paul Stewartf65320c2011-10-13 14:34:52 -070035}
36
Wade Guthrie9f62cd12013-05-15 10:40:42 -070037int Sockets::AttachFilter(int sockfd, struct sock_fprog *pf) const {
Paul Stewartac1328e2012-07-20 11:55:40 -070038 return setsockopt(sockfd, SOL_SOCKET, SO_ATTACH_FILTER, pf, sizeof(*pf));
39}
40
Wade Guthrie9f62cd12013-05-15 10:40:42 -070041int Sockets::Bind(int sockfd,
42 const struct sockaddr *addr,
43 socklen_t addrlen) const {
Darin Petkov633ac6f2011-07-08 13:56:13 -070044 return bind(sockfd, addr, addrlen);
45}
46
Wade Guthrie9f62cd12013-05-15 10:40:42 -070047int Sockets::BindToDevice(int sockfd, const std::string &device) const {
Paul Stewartf65320c2011-10-13 14:34:52 -070048 char dev_name[IFNAMSIZ];
49 CHECK_GT(sizeof(dev_name), device.length());
50 memset(&dev_name, 0, sizeof(dev_name));
51 snprintf(dev_name, sizeof(dev_name), "%s", device.c_str());
Gary Morain41780232012-07-31 15:08:31 -070052 return HANDLE_EINTR(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, &dev_name,
53 sizeof(dev_name)));
Paul Stewartf65320c2011-10-13 14:34:52 -070054}
55
Wade Guthrie9f62cd12013-05-15 10:40:42 -070056int Sockets::Close(int fd) const {
Gary Morain41780232012-07-31 15:08:31 -070057 return HANDLE_EINTR(close(fd));
Darin Petkov633ac6f2011-07-08 13:56:13 -070058}
59
Wade Guthrie9f62cd12013-05-15 10:40:42 -070060int Sockets::Connect(int sockfd,
61 const struct sockaddr *addr,
62 socklen_t addrlen) const {
Gary Morain41780232012-07-31 15:08:31 -070063 return HANDLE_EINTR(connect(sockfd, addr, addrlen));
Paul Stewartf65320c2011-10-13 14:34:52 -070064}
65
Wade Guthrie9f62cd12013-05-15 10:40:42 -070066int Sockets::Error() const {
Paul Stewartf65320c2011-10-13 14:34:52 -070067 return errno;
68}
69
Wade Guthrie9f62cd12013-05-15 10:40:42 -070070std::string Sockets::ErrorString() const {
Paul Stewartf65320c2011-10-13 14:34:52 -070071 return std::string(strerror(Error()));
72}
73
74int Sockets::GetSockName(int sockfd,
75 struct sockaddr *addr,
Wade Guthrie9f62cd12013-05-15 10:40:42 -070076 socklen_t *addrlen) const {
Paul Stewartf65320c2011-10-13 14:34:52 -070077 return getsockname(sockfd, addr, addrlen);
78}
79
80
Wade Guthrie9f62cd12013-05-15 10:40:42 -070081int Sockets::GetSocketError(int sockfd) const {
Paul Stewartf65320c2011-10-13 14:34:52 -070082 int error;
83 socklen_t optlen = sizeof(error);
84 if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &optlen) == 0) {
85 return error;
86 }
87 return -1;
88}
89
90
Wade Guthrie9f62cd12013-05-15 10:40:42 -070091int Sockets::Ioctl(int d, int request, void *argp) const {
Gary Morain41780232012-07-31 15:08:31 -070092 return HANDLE_EINTR(ioctl(d, request, argp));
Darin Petkove0a312e2011-07-20 13:45:28 -070093}
94
Wade Guthrie9f62cd12013-05-15 10:40:42 -070095int Sockets::Listen(int sockfd, int backlog) const {
Paul Stewartf65320c2011-10-13 14:34:52 -070096 return listen(sockfd, backlog);
97}
98
Wade Guthrie9f62cd12013-05-15 10:40:42 -070099ssize_t Sockets::RecvFrom(int sockfd,
100 void *buf,
101 size_t len,
102 int flags,
103 struct sockaddr *src_addr,
104 socklen_t *addrlen) const {
Gary Morain41780232012-07-31 15:08:31 -0700105 return HANDLE_EINTR(recvfrom(sockfd, buf, len, flags, src_addr, addrlen));
Paul Stewartac1328e2012-07-20 11:55:40 -0700106}
107
Wade Guthriefa2100e2013-05-15 10:11:22 -0700108int Sockets::Select(int nfds,
109 fd_set *readfds,
110 fd_set *writefds,
111 fd_set *exceptfds,
112 struct timeval *timeout) const {
113 return HANDLE_EINTR(select(nfds, readfds, writefds, exceptfds, timeout));
114}
115
Wade Guthrie9f62cd12013-05-15 10:40:42 -0700116ssize_t Sockets::Send(int sockfd,
117 const void *buf,
118 size_t len,
119 int flags) const {
Gary Morain41780232012-07-31 15:08:31 -0700120 return HANDLE_EINTR(send(sockfd, buf, len, flags));
Darin Petkov633ac6f2011-07-08 13:56:13 -0700121}
122
Wade Guthrie9f62cd12013-05-15 10:40:42 -0700123ssize_t Sockets::SendTo(int sockfd,
124 const void *buf,
125 size_t len,
126 int flags,
127 const struct sockaddr *dest_addr,
128 socklen_t addrlen) const {
Gary Morain41780232012-07-31 15:08:31 -0700129 return HANDLE_EINTR(sendto(sockfd, buf, len, flags, dest_addr, addrlen));
Darin Petkov633ac6f2011-07-08 13:56:13 -0700130}
131
Wade Guthrie9f62cd12013-05-15 10:40:42 -0700132int Sockets::SetNonBlocking(int sockfd) const {
Gary Morain41780232012-07-31 15:08:31 -0700133 return HANDLE_EINTR(
134 fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK));
Paul Stewartf65320c2011-10-13 14:34:52 -0700135}
136
Wade Guthrie9f62cd12013-05-15 10:40:42 -0700137int Sockets::SetReceiveBuffer(int sockfd, int size) const {
Julius Wernerf253c842012-12-20 14:52:30 -0800138 // Note: kernel will set buffer to 2*size to allow for struct skbuff overhead
139 return setsockopt(sockfd, SOL_SOCKET, SO_RCVBUFFORCE, &size, sizeof(size));
140}
141
Wade Guthrie9f62cd12013-05-15 10:40:42 -0700142int Sockets::ShutDown(int sockfd, int how) const {
Prathmesh Prabhu40daa012013-04-03 10:35:03 -0700143 return HANDLE_EINTR(shutdown(sockfd, how));
144}
145
Wade Guthrie9f62cd12013-05-15 10:40:42 -0700146int Sockets::Socket(int domain, int type, int protocol) const {
Darin Petkov633ac6f2011-07-08 13:56:13 -0700147 return socket(domain, type, protocol);
148}
149
Darin Petkove0a312e2011-07-20 13:45:28 -0700150ScopedSocketCloser::ScopedSocketCloser(Sockets *sockets, int fd)
151 : sockets_(sockets),
152 fd_(fd) {}
153
154ScopedSocketCloser::~ScopedSocketCloser() {
155 sockets_->Close(fd_);
156 fd_ = -1;
157}
158
Darin Petkov633ac6f2011-07-08 13:56:13 -0700159} // namespace shill