Changeset 745 for trunk/server/lib/tsocket
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 1 deleted
- 5 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/lib/tsocket/tsocket.c
r414 r745 47 47 return -1; 48 48 default: 49 *perrno = EIO; 50 return -1; 49 break; 51 50 } 52 51 -
trunk/server/lib/tsocket/tsocket.h
r480 r745 84 84 85 85 /** 86 * @brief Get a string representa ion of the endpoint.86 * @brief Get a string representation of the endpoint. 87 87 * 88 88 * This function creates a string representation of the endpoint for debugging. … … 102 102 * @return The address as a string representation, NULL on error. 103 103 * 104 * @see tsocket_address_is_inet() 104 105 * @see tsocket_address_inet_addr_string() 105 106 * @see tsocket_address_inet_port() … … 486 487 * @{ 487 488 */ 489 490 /** 491 * @brief Find out if the tsocket_address represents an ipv4 or ipv6 endpoint. 492 * 493 * @param[in] addr The tsocket_address pointer 494 * 495 * @param[in] fam The family can be can be "ipv4", "ipv6" or "ip". With 496 * "ip" is autodetects "ipv4" or "ipv6" based on the 497 * addr. 498 * 499 * @return true if addr represents an address of the given family, 500 * otherwise false. 501 */ 502 bool tsocket_address_is_inet(const struct tsocket_address *addr, const char *fam); 488 503 489 504 #if DOXYGEN … … 534 549 * @return A newly allocated string of the address, NULL on error 535 550 * with errno set. 551 * 552 * @see tsocket_address_is_inet() 536 553 */ 537 554 char *tsocket_address_inet_addr_string(const struct tsocket_address *addr, … … 559 576 uint16_t port); 560 577 578 /** 579 * @brief Find out if the tsocket_address represents an unix domain endpoint. 580 * 581 * @param[in] addr The tsocket_address pointer 582 * 583 * @return true if addr represents an unix domain endpoint, 584 * otherwise false. 585 */ 586 bool tsocket_address_is_unix(const struct tsocket_address *addr); 587 561 588 #ifdef DOXYGEN 562 589 /** … … 570 597 * 571 598 * @return 0 on success, -1 on error with errno set. 599 * 600 * @see tsocket_address_is_unix() 572 601 */ 573 602 int tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx, … … 696 725 * @param[in] mem_ctx The talloc memory context to use. 697 726 * 698 * @param[ in]stream A tstream_context pointer to setup the tcp communication727 * @param[out] stream A tstream_context pointer to setup the tcp communication 699 728 * on. This function will allocate the memory. 729 * 730 * @param[out] local The real 'inet' tsocket_address of the local endpoint. 731 * This parameter is optional and can be NULL. 700 732 * 701 733 * @return 0 on success, -1 on error with perrno set. … … 704 736 int *perrno, 705 737 TALLOC_CTX *mem_ctx, 706 struct tstream_context **stream); 738 struct tstream_context **stream, 739 struct tsocket_address **local) 707 740 #else 708 741 int _tstream_inet_tcp_connect_recv(struct tevent_req *req, … … 710 743 TALLOC_CTX *mem_ctx, 711 744 struct tstream_context **stream, 745 struct tsocket_address **local, 712 746 const char *location); 713 #define tstream_inet_tcp_connect_recv(req, perrno, mem_ctx, stream ) \714 _tstream_inet_tcp_connect_recv(req, perrno, mem_ctx, stream, \747 #define tstream_inet_tcp_connect_recv(req, perrno, mem_ctx, stream, local) \ 748 _tstream_inet_tcp_connect_recv(req, perrno, mem_ctx, stream, local, \ 715 749 __location__) 716 750 #endif … … 874 908 * freed. If you still want to use the fd you have have to create a duplicate. 875 909 * 876 * @param[in] mem_ctx The talloc memory context to use. 877 * 878 * @param[in] fd The non blocking fd to use! 879 * 880 * @param[in] stream The filed tstream_context you allocated before. 881 * 882 * @return 0 on success, -1 on error with errno set. 883 * 884 * @warning You should read the tsocket_bsd.c code and unterstand it in order 885 * use this function. 910 * @param[in] mem_ctx The talloc memory context to use. 911 * 912 * @param[in] fd The non blocking fd to use! 913 * 914 * @param[out] stream A pointer to store an allocated tstream_context. 915 * 916 * @return 0 on success, -1 on error. 917 * 918 * Example: 919 * @code 920 * fd2 = dup(fd); 921 * rc = tstream_bsd_existing_socket(mem_ctx, fd2, &tstream); 922 * if (rc < 0) { 923 * stream_terminate_connection(conn, "named_pipe_accept: out of memory"); 924 * return; 925 * } 926 * @endcode 927 * 928 * @warning This is an internal function. You should read the code to fully 929 * understand it if you plan to use it. 886 930 */ 887 931 int tstream_bsd_existing_socket(TALLOC_CTX *mem_ctx, -
trunk/server/lib/tsocket/tsocket_bsd.c
r480 r745 264 264 265 265 bsda->sa_socklen = sa_socklen; 266 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 267 bsda->u.sa.sa_len = bsda->sa_socklen; 268 #endif 266 269 267 270 *_addr = addr; … … 292 295 293 296 memcpy(sa, &bsda->u.ss, sa_socklen); 297 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 298 sa->sa_len = sa_socklen; 299 #endif 294 300 return sa_socklen; 301 } 302 303 bool tsocket_address_is_inet(const struct tsocket_address *addr, const char *fam) 304 { 305 struct tsocket_address_bsd *bsda = talloc_get_type(addr->private_data, 306 struct tsocket_address_bsd); 307 308 if (!bsda) { 309 return false; 310 } 311 312 switch (bsda->u.sa.sa_family) { 313 case AF_INET: 314 if (strcasecmp(fam, "ip") == 0) { 315 return true; 316 } 317 318 if (strcasecmp(fam, "ipv4") == 0) { 319 return true; 320 } 321 322 return false; 323 #ifdef HAVE_IPV6 324 case AF_INET6: 325 if (strcasecmp(fam, "ip") == 0) { 326 return true; 327 } 328 329 if (strcasecmp(fam, "ipv6") == 0) { 330 return true; 331 } 332 333 return false; 334 #endif 335 } 336 337 return false; 295 338 } 296 339 … … 465 508 466 509 return 0; 510 } 511 512 bool tsocket_address_is_unix(const struct tsocket_address *addr) 513 { 514 struct tsocket_address_bsd *bsda = talloc_get_type(addr->private_data, 515 struct tsocket_address_bsd); 516 517 if (!bsda) { 518 return false; 519 } 520 521 switch (bsda->u.sa.sa_family) { 522 case AF_UNIX: 523 return true; 524 } 525 526 return false; 467 527 } 468 528 … … 847 907 ZERO_STRUCTP(bsda); 848 908 bsda->sa_socklen = sizeof(bsda->u.ss); 909 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 910 bsda->u.sa.sa_len = bsda->sa_socklen; 911 #endif 849 912 850 913 ret = recvfrom(bsds->fd, state->buf, state->len, 0, … … 1054 1117 } 1055 1118 1119 TALLOC_FREE(bsds->fde); 1056 1120 ret = close(bsds->fd); 1057 1121 bsds->fd = -1; … … 1184 1248 fd = socket(sa_fam, SOCK_DGRAM, 0); 1185 1249 if (fd < 0) { 1186 return fd;1250 return -1; 1187 1251 } 1188 1252 1189 1253 fd = tsocket_bsd_common_prepare_fd(fd, true); 1190 1254 if (fd < 0) { 1191 return fd;1255 return -1; 1192 1256 } 1193 1257 … … 1217 1281 talloc_free(dgram); 1218 1282 errno = saved_errno; 1219 return ret;1283 return -1; 1220 1284 } 1221 1285 } … … 1231 1295 talloc_free(dgram); 1232 1296 errno = saved_errno; 1233 return ret;1297 return -1; 1234 1298 } 1235 1299 } … … 1244 1308 talloc_free(dgram); 1245 1309 errno = saved_errno; 1246 return ret;1310 return -1; 1247 1311 } 1248 1312 } … … 1254 1318 talloc_free(dgram); 1255 1319 errno = saved_errno; 1256 return ret;1320 return -1; 1257 1321 } 1258 1322 } … … 1270 1334 talloc_free(dgram); 1271 1335 errno = saved_errno; 1272 return ret;1336 return -1; 1273 1337 } 1274 1338 } … … 1610 1674 base = (uint8_t *)state->vector[0].iov_base; 1611 1675 base += ret; 1612 state->vector[0].iov_base = base;1676 state->vector[0].iov_base = (void *)base; 1613 1677 state->vector[0].iov_len -= ret; 1614 1678 break; … … 1770 1834 base = (uint8_t *)state->vector[0].iov_base; 1771 1835 base += ret; 1772 state->vector[0].iov_base = base;1836 state->vector[0].iov_base = (void *)base; 1773 1837 state->vector[0].iov_len -= ret; 1774 1838 break; … … 1841 1905 } 1842 1906 1907 TALLOC_FREE(bsds->fde); 1843 1908 ret = close(bsds->fd); 1844 1909 bsds->fd = -1; … … 1918 1983 struct tevent_fd *fde; 1919 1984 struct tstream_conext *stream; 1985 struct tsocket_address *local; 1920 1986 }; 1921 1987 … … 1936 2002 void *private_data); 1937 2003 1938 static struct tevent_req * 2004 static struct tevent_req *tstream_bsd_connect_send(TALLOC_CTX *mem_ctx, 1939 2005 struct tevent_context *ev, 1940 2006 int sys_errno, … … 1947 2013 talloc_get_type_abort(local->private_data, 1948 2014 struct tsocket_address_bsd); 2015 struct tsocket_address_bsd *lrbsda = NULL; 1949 2016 struct tsocket_address_bsd *rbsda = 1950 2017 talloc_get_type_abort(remote->private_data, … … 2026 2093 } 2027 2094 2095 if (is_inet) { 2096 state->local = tsocket_address_create(state, 2097 &tsocket_address_bsd_ops, 2098 &lrbsda, 2099 struct tsocket_address_bsd, 2100 __location__ "bsd_connect"); 2101 if (tevent_req_nomem(state->local, req)) { 2102 goto post; 2103 } 2104 2105 ZERO_STRUCTP(lrbsda); 2106 lrbsda->sa_socklen = sizeof(lrbsda->u.ss); 2107 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 2108 lrbsda->u.sa.sa_len = lrbsda->sa_socklen; 2109 #endif 2110 } 2111 2028 2112 state->fd = socket(sa_fam, SOCK_STREAM, 0); 2029 2113 if (state->fd == -1) { … … 2082 2166 } 2083 2167 if (tevent_req_error(req, err)) { 2168 goto post; 2169 } 2170 2171 if (!state->local) { 2172 tevent_req_done(req); 2173 goto post; 2174 } 2175 2176 ret = getsockname(state->fd, &lrbsda->u.sa, &lrbsda->sa_socklen); 2177 if (ret == -1) { 2178 tevent_req_error(req, errno); 2084 2179 goto post; 2085 2180 } … … 2114 2209 struct tstream_bsd_connect_state *state = tevent_req_data(req, 2115 2210 struct tstream_bsd_connect_state); 2211 struct tsocket_address_bsd *lrbsda = NULL; 2116 2212 int ret; 2117 2213 int error=0; … … 2136 2232 } 2137 2233 2234 if (!state->local) { 2235 tevent_req_done(req); 2236 return; 2237 } 2238 2239 lrbsda = talloc_get_type_abort(state->local->private_data, 2240 struct tsocket_address_bsd); 2241 2242 ret = getsockname(state->fd, &lrbsda->u.sa, &lrbsda->sa_socklen); 2243 if (ret == -1) { 2244 tevent_req_error(req, errno); 2245 return; 2246 } 2247 2138 2248 tevent_req_done(req); 2139 2249 } … … 2143 2253 TALLOC_CTX *mem_ctx, 2144 2254 struct tstream_context **stream, 2255 struct tsocket_address **local, 2145 2256 const char *location) 2146 2257 { … … 2161 2272 TALLOC_FREE(state->fde); 2162 2273 state->fd = -1; 2274 2275 if (local) { 2276 *local = talloc_move(mem_ctx, &state->local); 2277 } 2163 2278 } 2164 2279 … … 2200 2315 TALLOC_CTX *mem_ctx, 2201 2316 struct tstream_context **stream, 2317 struct tsocket_address **local, 2202 2318 const char *location) 2203 2319 { 2204 return tstream_bsd_connect_recv(req, perrno, mem_ctx, stream, location); 2320 return tstream_bsd_connect_recv(req, perrno, 2321 mem_ctx, stream, local, 2322 location); 2205 2323 } 2206 2324 … … 2235 2353 const char *location) 2236 2354 { 2237 return tstream_bsd_connect_recv(req, perrno, mem_ctx, stream, location); 2355 return tstream_bsd_connect_recv(req, perrno, 2356 mem_ctx, stream, NULL, 2357 location); 2238 2358 } 2239 2359 -
trunk/server/lib/tsocket/tsocket_guide.txt
r414 r745 24 24 =============================== 25 25 26 The tsocket_address represents an socket endpoint genericly.27 As it's like an abstract class it has no specificconstructor.28 The specific constructors are descripted later sections.29 30 There's a function get the string representation of the 31 endpoint for debugging. Callers should not try to parse32 the string! The should use additional methods of the specific 33 tsocket_address implemention to get more details.26 A tsocket_address represents a generic socket endpoint. 27 It behaves like an abstract class, therefore it has no direct constructor. 28 Constructors are described in later sections of this document. 29 30 A function get the string representation of an endpoint for debugging is 31 available but callers SHOULD NOT try to parse this string. To get more 32 details callers should use getter methods of the specific tsocket_address 33 implemention. 34 34 35 35 char *tsocket_address_string(const struct tsocket_address *addr, 36 36 TALLOC_CTX *mem_ctx); 37 37 38 There's a function to create a copy of the tsocket_address.39 This is useful whenbefore doing modifications to a socket38 A function to create a copy of the tsocket_address is also avilable. 39 This is useful before doing modifications to a socket 40 40 via additional methods of the specific tsocket_address implementation. 41 41 … … 48 48 The tdgram_context is like an abstract class for datagram 49 49 based sockets. The interface provides async 'tevent_req' based 50 functions on top functionality is similar to the 51 recvfrom(2)/sendto(2)/close(2) syscalls. 50 functions similar to recvfrom(2)/sendto(2)/close(2) syscalls. 52 51 53 52 The tdgram_recvfrom_send() method can be called to ask for the 54 next available datagram onthe abstracted tdgram_context.53 next available datagram from the abstracted tdgram_context. 55 54 It returns a 'tevent_req' handle, where the caller can register 56 55 a callback with tevent_req_set_callback(). The callback is triggered 57 when a datagram is available or an error happened.56 when a datagram is available or an error occurs. 58 57 59 58 The callback is then supposed to get the result by calling … … 123 122 =============================== 124 123 125 Thetstream_context is like an abstract class for stream124 A tstream_context is like an abstract class for stream 126 125 based sockets. The interface provides async 'tevent_req' based 127 functions on top functionality is similar to the 128 readv(2)/writev(2)/close(2) syscalls. 129 130 The tstream_pending_bytes() function is able to report 131 how much bytes of the incoming stream have arrived 132 but not consumed yet. It returns -1 and sets 'errno' on failure. 133 Otherwise it returns the number of uncomsumed bytes 134 (it can return 0!). 126 functions similar to the readv(2)/writev(2)/close(2) syscalls. 127 128 The tstream_pending_bytes() function is able to report how many bytes of 129 the incoming stream have been received but have not been consumed yet. 130 It returns -1 and sets 'errno' on failure. 131 Otherwise it returns the number of uncomsumed bytes (it can return 0!). 135 132 136 133 ssize_t tstream_pending_bytes(struct tstream_context *stream); 137 134 138 The tstream_readv_send() method can be called to read fora135 The tstream_readv_send() method can be called to read a 139 136 specific amount of bytes from the stream into the buffers 140 137 of the given iovec vector. The caller has to preallocate the buffers … … 144 141 where the caller can register a callback with tevent_req_set_callback(). 145 142 The callback is triggered when all iovec buffers are completely 146 filled with bytes from the socket or an error happened.143 filled with bytes from the socket or an error occurs. 147 144 148 145 The callback is then supposed to get the result by calling 149 146 tstream_readv_recv() on the 'tevent_req'. It returns -1 150 147 and sets '*perrno' to the actual 'errno' on failure. 151 Otherwise it returns the length of the datagram 152 (0 is never returned!). 148 Otherwise it returns the length of the datagram (0 is never returned!). 153 149 154 150 The caller can only have one outstanding tstream_readv_send() … … 166 162 The tstream_writev_send() method can be called to write 167 163 buffers in the given iovec vector into the stream socket. 168 It 's invalid to pass an empty vector.164 It is invalid to pass an empty vector. 169 165 tstream_writev_send() returns a 'tevent_req' handle, 170 166 where the caller can register a callback with tevent_req_set_callback(). … … 190 186 int *perrno); 191 187 192 The tstream_disconnect_send() method should be used to normally188 The tstream_disconnect_send() method should normally be used to 193 189 shutdown/close the abstracted socket. 194 190 … … 209 205 ============================ 210 206 211 In order to make the live easier for callers whichwant to implement207 In order to simplify the job, for callers that want to implement 212 208 a function to receive a full PDU with a single async function pair, 213 there're some helper functions.209 some helper functions are provided. 214 210 215 211 The caller can use the tstream_readv_pdu_send() function … … 217 213 The caller needs to provide a "next_vector" function and a private 218 214 state for this function. The tstream_readv_pdu engine will ask 219 the next_vector function for the next iovec ve tor to be filled.215 the next_vector function for the next iovec vector to be used. 220 216 There's a tstream_readv_send/recv pair for each vector returned 221 217 by the next_vector function. If the next_vector function detects … … 223 219 of the tevent_req (returned by tstream_readv_pdu_send()) is triggered. 224 220 Note: the buffer allocation is completely up to the next_vector function 225 and it 's private state.221 and its private state. 226 222 227 223 See the 'dcerpc_read_ncacn_packet_send/recv' functions in Samba as an … … 245 241 =========================================== 246 242 247 There're some cases where the caller wants doesn't care aboutthe248 order of doing IO on the abstracted sockets.243 In some cases the caller doesn't care about the IO ordering on the 244 abstracted socket. 249 245 (Remember at the low level there's always only one IO in a specific 250 246 direction allowed, only one tdgram_sendto_send() at a time). 251 247 252 There're some helpers using 'tevent_queue' to make it easier 253 for callers. The functions just get a 'queue' argument 254 and serialize theoperations.248 Some helpers that use 'tevent_queue' are avilable to simplify handling 249 multiple IO requests. The functions just get a 'queue' argument and 250 internally serialize all operations. 255 251 256 252 struct tevent_req *tdgram_sendto_queue_send(TALLOC_CTX *mem_ctx, … … 296 292 (dns names are not allowed!). But it's valid to pass NULL, 297 293 which gets mapped to "0.0.0.0" or "::". 298 It return -1 and seterrno on error. Otherwise it returns 0.294 It returns -1 and sets errno on error. Otherwise it returns 0. 299 295 300 296 int tsocket_address_inet_from_strings(TALLOC_CTX *mem_ctx, … … 343 339 you can use the tsocket_address_unix_path() function. 344 340 It will return NULL and set errno to EINVAL if the tsocket_address 345 doesn't represent a nunix domain endpoint path.341 doesn't represent a unix domain endpoint path. 346 342 347 343 char *tsocket_address_unix_path(const struct tsocket_address *addr, … … 372 368 struct tdgram_context **dgram); 373 369 374 You can use tstream_inet_tcp_connect_send to async 370 You can use tstream_inet_tcp_connect_send to asynchronously 375 371 connect to a remote ipv4 or ipv6 TCP endpoint and create a 376 372 tstream_context for the stream based communication. "local_address" has to be … … 398 394 struct tstream_context **stream); 399 395 400 You can use tstream_unix_connect_send to async 396 You can use tstream_unix_connect_send to asynchronously 401 397 connect to a unix domain endpoint and create a 402 398 tstream_context for the stream based communication. … … 439 435 for that. This should only be used if really needed, because of 440 436 already existing fixed APIs. Only AF_INET, AF_INET6 and AF_UNIX 441 sockets are allowed. The function returns -1 and set errno on error.437 sockets are allowed. The function returns -1 and sets errno on error. 442 438 Otherwise it returns 0. 443 439
Note:
See TracChangeset
for help on using the changeset viewer.