00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "ux.hpp"
00019
00020 #include <arpa/inet.h>
00021
00022 using namespace Ux;
00023
00024
00025
00026
00027 void SockIPv4::set(const char *str)
00028 {
00029 switch (::inet_pton(AF_INET, str, &ipv4)) {
00030 case 0:
00031 throw Error(EINVAL);
00032 case -1:
00033 throw Error(errno);
00034 }
00035 }
00036
00037
00038
00039
00040 const char *SockIPv4::get_string(char *buf, socklen_t bufsize) const
00041 {
00042 if (::inet_ntop(AF_INET, &ipv4, buf, bufsize) == NULL)
00043 throw Error(errno);
00044 return buf;
00045 }
00046
00047
00048
00049
00050 void SockIPv6::set(uint8_t *ip = NULL)
00051 {
00052 if (ip == NULL)
00053 memset(ipv6, 0, sizeof(ipv6));
00054 else
00055 memcpy(ipv6, ip, sizeof(ipv6));
00056 }
00057
00058
00059
00060
00061 void SockIPv6::set(const char *str)
00062 {
00063 switch (::inet_pton(AF_INET6, str, ipv6)) {
00064 case 0:
00065 throw Error(EINVAL);
00066 case -1:
00067 throw Error(errno);
00068 }
00069 }
00070
00071
00072
00073
00074 const char *SockIPv6::get_string(char *buf, socklen_t bufsize) const
00075 {
00076 if (::inet_ntop(AF_INET6, ipv6, buf, bufsize) == NULL)
00077 throw Error(errno);
00078 return buf;
00079 }
00080
00081
00082
00083
00084 void SockAddrUn::set(const char *path)
00085 {
00086 struct sockaddr_un *p = (struct sockaddr_un *)&sa_storage;
00087
00088 p->sun_family = AF_UNIX;
00089 if (strlen(path) >= sizeof(p->sun_path))
00090 throw Error(ENAMETOOLONG);
00091 strcpy(p->sun_path, path);
00092 set_len(sizeof(struct sockaddr_un));
00093 }
00094
00095
00096
00097
00098 void SockAddrIn::set(in_port_t port, struct in_addr& sa)
00099 {
00100 struct sockaddr_in *p = (struct sockaddr_in *)&sa_storage;
00101
00102 p->sin_family = AF_INET;
00103 p->sin_port = port;
00104 p->sin_addr = sa;
00105 set_len(sizeof(struct sockaddr_in));
00106 }
00107
00108
00109
00110
00111 void SockAddrIn::set(in_port_t port, in_addr_t ipv4)
00112 {
00113 struct in_addr sa;
00114
00115 sa.s_addr = ipv4;
00116 set(port, sa);
00117 }
00118
00119
00120
00121
00122 void SockAddrIn::set(in_port_t port, const char *dotted)
00123 {
00124 set(port, SockIPv4(dotted).get_ipv4());
00125 }
00126
00127
00128
00129
00130 void SockAddr::getaddrinfo(const char *nodename, const char *servname,
00131 const struct addrinfo *hint, struct addrinfo **infop)
00132 {
00133 int r;
00134
00135 if ((r = ::getaddrinfo(nodename, servname, hint, infop)) != 0)
00136 throw Error(r, EC_EAI);
00137 }
00138
00139
00140
00141
00142 void SockAddr::getaddrinfo(const char *nodename, const char *servname, int family, int type,
00143 int flags, struct addrinfo **infop)
00144 {
00145 struct addrinfo hint;
00146
00147 memset(&hint, 0, sizeof(hint));
00148 hint.ai_family = family;
00149 hint.ai_socktype = type;
00150 hint.ai_flags = flags;
00151 getaddrinfo(nodename, servname, &hint, infop);
00152 }
00153
00154
00155
00156
00157 void SockAddr::set_server(const char *nodename, const char *servname)
00158 {
00159 struct addrinfo *infop;
00160
00161 getaddrinfo(nodename, servname, AF_INET, SOCK_STREAM, AI_PASSIVE, &infop);
00162 memcpy(&sa_storage, infop->ai_addr, infop->ai_addrlen);
00163 set_len(infop->ai_addrlen);
00164 set_protocol(infop->ai_protocol);
00165 }
00166
00167
00168
00169
00170 void SockAddr::getnameinfo(const struct sockaddr *sa, socklen_t sa_len, char *nodename,
00171 socklen_t nodelen, char *servname, socklen_t servlen, unsigned flags)
00172 {
00173 int r;
00174
00175 if ((r = ::getnameinfo(sa, sa_len, nodename, nodelen, servname, servlen, flags)) != 0)
00176 throw Error(r, EC_EAI);
00177 }
00178
00179
00180
00181
00182 void Socket::socket(int domain, int type, int protocol)
00183 {
00184 if ((fd = ::socket(domain, type, protocol)) == -1)
00185 throw Error(errno);
00186 }
00187
00188
00189
00190
00191 void Socket::bind(const SockAddr& sa)
00192 {
00193 if (::bind(fd, sa.get_addr(), sa.get_len()) == -1)
00194 throw Error(errno);
00195 }
00196
00197
00198
00199
00200 void Socket::listen(int backlog)
00201 {
00202 if (::listen(fd, backlog) == -1)
00203 throw Error(errno);
00204 }
00205
00206
00207
00208
00209 Socket Socket::accept(SockAddr *sa)
00210 {
00211 int r;
00212
00213 if (sa == NULL)
00214 r = ::accept(fd, NULL, NULL);
00215 else
00216 r = ::accept(fd, sa->get_addr(), sa->get_len_ptr());
00217 if (r == -1)
00218 throw Error(errno);
00219 return Socket(r);
00220 }
00221
00222
00223
00224
00225 void Socket::connect(const SockAddr& sa)
00226 {
00227 if (::connect(fd, sa.get_addr(), sa.get_len()) == -1)
00228 throw Error(errno);
00229 }
00230
00231
00232
00233
00234 void Socket::setsockopt(int level, int option, const void *value, socklen_t value_len)
00235 {
00236 if (::setsockopt(fd, level, option, value, value_len) == -1)
00237 throw Error(errno);
00238 }
00239
00240
00241
00242
00243 void Socket::getsockopt(int level, int option, void *value, socklen_t& value_len)
00244 {
00245 if (::getsockopt(fd, level, option, value, &value_len) == -1)
00246 throw Error(errno);
00247 }
00248
00249
00250
00251
00252 ssize_t Socket::sendto(const void *message, size_t length, int flags, const struct sockaddr *sa,
00253 socklen_t sa_len)
00254 {
00255 ssize_t n;
00256
00257 if ((n = ::sendto(fd, message, length, flags, sa, sa_len)) == -1)
00258 throw Error(errno);
00259 return n;
00260 }
00261
00262
00263
00264
00265 ssize_t Socket::recvfrom(void *buffer, size_t length, int flags, struct sockaddr *sa,
00266 socklen_t *sa_len)
00267 {
00268 ssize_t n;
00269
00270 if ((n = ::recvfrom(fd, buffer, length, flags, sa, sa_len)) == -1)
00271 throw Error(errno);
00272 return n;
00273 }
00274
00275
00276
00277
00278 ssize_t Socket::sendmsg(const struct msghdr *message, int flags)
00279 {
00280 ssize_t n;
00281
00282 if ((n = ::sendmsg(fd, message, flags)) == -1)
00283 throw Error(errno);
00284 return n;
00285 }
00286
00287
00288
00289
00290 ssize_t Socket::recvmsg(struct msghdr *message, int flags)
00291 {
00292 ssize_t n;
00293
00294 if ((n = ::recvmsg(fd, message, flags)) == -1)
00295 throw Error(errno);
00296 return n;
00297 }
00298
00299
00300
00301
00302 ssize_t Socket::send(const void *data, size_t length, int flags)
00303 {
00304 ssize_t n;
00305
00306 if ((n = ::send(fd, data, length, flags)) == -1)
00307 throw Error(errno);
00308 return n;
00309 }
00310
00311
00312
00313
00314 ssize_t Socket::recv(void *buffer, size_t length, int flags)
00315 {
00316 ssize_t n;
00317
00318 if ((n = ::recv(fd, buffer, length, flags)) == -1)
00319 throw Error(errno);
00320 return n;
00321 }
00322
00323
00324
00325 void Socket::getpeername(SockAddr& sa)
00326 {
00327 if (::getpeername(fd, sa.get_addr(), sa.get_len_ptr()) == -1)
00328 throw Error(errno);
00329 }
00330
00331
00332
00333
00334 void Socket::getsockname(SockAddr& sa)
00335 {
00336 if (::getsockname(fd, sa.get_addr(), sa.get_len_ptr()) == -1)
00337 throw Error(errno);
00338 }
00339
00340
00341
00342
00343 void Socket::socketpair(Socket sv[2], int domain, int type, int protocol)
00344 {
00345 int fds[2];
00346
00347 if (::socketpair(domain, type, protocol, fds) == -1)
00348 throw Error(errno);
00349 sv[0].set(fds[0]);
00350 sv[1].set(fds[1]);
00351 }
00352
00353
00354
00355
00356 void Socket::shutdown(int how)
00357 {
00358 if (::shutdown(fd, how) == -1)
00359 throw Error(errno);
00360 }
00361
00362
00363
00364
00365 bool Socket::sockatmark(void)
00366 {
00367 #if _XOPEN_VERSION >= 600
00368 int r;
00369
00370 if ((r = ::sockatmark(fd)) == -1)
00371 throw Error(errno);
00372 return r == 1;
00373 #else
00374 throw Error(ENOSYS);
00375 #endif
00376 }