10 #ifdef HAVE_NETINET_IN_H
11 #include <netinet/in.h> /* OS/2 needs this after sys/types.h */
13 #ifdef HAVE_SYS_SOCKET_H
14 #include <sys/socket.h> /* OS/2 needs this after sys/types.h */
17 #include <fcntl.h> /* OS/2 needs this after sys/types.h */
22 #ifdef HAVE_WS2TCPIP_H
23 #include <ws2tcpip.h> /* socklen_t for MinGW */
26 #ifdef HAVE_GETIFADDRS
34 #include <ifaddrs.h> /* getifaddrs() */
36 #endif /* HAVE_GETIFADDRS */
38 #ifdef HAVE_ARPA_INET_H
39 #include <arpa/inet.h>
44 #include "config/options.h"
45 #include "main/select.h"
46 #include "network/connection.h"
47 #include "network/dns.h"
48 #include "network/socket.h"
49 #include "network/ssl/socket.h"
50 #include "osdep/osdep.h"
51 #include "osdep/getifaddrs.h"
52 #include "protocol/http/blacklist.h"
53 #include "protocol/protocol.h"
54 #include "protocol/uri.h"
55 #include "util/error.h"
56 #include "util/memory.h"
57 #include "util/string.h"
60 /* Holds information used during the connection establishing phase. */
62 struct sockaddr_storage
*addr
; /* Array of found addresses. */
63 int addrno
; /* Number of found addresses. */
64 int triedno
; /* Index of last tried address */
65 socket_connect_T done
; /* Callback signaled when connected. */
66 void *dnsquery
; /* Pointer to DNS query info. */
67 int port
; /* Which port to bind to. */
68 int ip_family
; /* If non-zero, force to IP version. */
69 struct uri
*uri
; /* For updating the blacklist. */
72 /** For detecting whether a struct socket has been deleted while a
73 * function was using it. */
74 struct socket_weak_ref
{
75 LIST_HEAD(struct socket_weak_ref
);
77 /** done_socket() resets this to NULL. */
78 struct socket
*socket
;
81 static INIT_LIST_OF(struct socket_weak_ref
, socket_weak_refs
);
83 /* To enable logging of tranfers, for debugging purposes. */
86 #define DEBUG_TRANSFER_LOGFILE "/tmp/log"
89 debug_transfer_log(unsigned char *data
, int len
)
91 int fd
= open(DEBUG_TRANSFER_LOGFILE
, O_WRONLY
| O_APPEND
| O_CREAT
, 0622);
96 write(fd
, data
, len
< 0 ? strlen(data
) : len
);
99 #undef DEBUG_TRANSFER_LOGFILE
102 #define debug_transfer_log(data, len)
106 static struct connect_info
*
107 init_connection_info(struct uri
*uri
, struct socket
*socket
,
108 socket_connect_T connect_done
)
110 struct connect_info
*connect_info
= mem_calloc(1, sizeof(*connect_info
));
112 if (!connect_info
) return NULL
;
114 connect_info
->done
= connect_done
;
115 connect_info
->port
= get_uri_port(uri
);
116 connect_info
->ip_family
= uri
->ip_family
;
117 connect_info
->triedno
= -1;
118 connect_info
->addr
= NULL
;
119 connect_info
->uri
= get_uri_reference(uri
);
125 done_connection_info(struct socket
*socket
)
127 struct connect_info
*connect_info
= socket
->connect_info
;
129 assert(socket
->connect_info
);
131 if (connect_info
->dnsquery
) kill_dns_request(&connect_info
->dnsquery
);
133 mem_free_if(connect_info
->addr
);
134 done_uri(connect_info
->uri
);
135 mem_free_set(&socket
->connect_info
, NULL
);
139 init_socket(void *conn
, struct socket_operations
*ops
)
141 struct socket
*socket
;
143 socket
= mem_calloc(1, sizeof(*socket
));
144 if (!socket
) return NULL
;
154 done_socket(struct socket
*socket
)
156 struct socket_weak_ref
*ref
;
158 close_socket(socket
);
160 if (socket
->connect_info
)
161 done_connection_info(socket
);
163 mem_free_set(&socket
->read_buffer
, NULL
);
164 mem_free_set(&socket
->write_buffer
, NULL
);
166 foreach(ref
, socket_weak_refs
) {
167 if (ref
->socket
== socket
)
173 close_socket(struct socket
*socket
)
175 if (socket
->fd
== -1) return;
177 if (socket
->ssl
) ssl_close(socket
);
180 clear_handlers(socket
->fd
);
185 dns_exception(struct socket
*socket
)
187 connect_socket(socket
, connection_state(S_EXCEPT
));
191 exception(struct socket
*socket
)
193 socket
->ops
->retry(socket
, connection_state(S_EXCEPT
));
198 timeout_socket(struct socket
*socket
)
200 if (!socket
->connect_info
) {
201 socket
->ops
->retry(socket
, connection_state(S_TIMEOUT
));
205 /* Is the DNS resolving still in progress? */
206 if (socket
->connect_info
->dnsquery
) {
207 socket
->ops
->done(socket
, connection_state(S_TIMEOUT
));
211 /* Try the next address, */
212 connect_socket(socket
, connection_state(S_TIMEOUT
));
214 /* Reset the timeout if connect_socket() started a new attempt
216 if (socket
->connect_info
)
217 socket
->ops
->set_timeout(socket
, connection_state(0));
223 dns_found(struct socket
*socket
, struct sockaddr_storage
*addr
, int addrlen
)
225 struct connect_info
*connect_info
= socket
->connect_info
;
229 socket
->ops
->done(socket
, connection_state(S_NO_DNS
));
233 assert(connect_info
);
235 size
= sizeof(*addr
) * addrlen
;
237 connect_info
->addr
= mem_alloc(size
);
238 if (!connect_info
->addr
) {
239 socket
->ops
->done(socket
, connection_state(S_OUT_OF_MEM
));
243 memcpy(connect_info
->addr
, addr
, size
);
244 connect_info
->addrno
= addrlen
;
246 /* XXX: Passing non-result state here is bad but a lack of alternatives
247 * makes it so. Well adding get_state() socket operation could maybe fix
248 * it but the returned state would most likely be a non-result one at
249 * this point in the connection lifecycle. This will, however, only be a
250 * problem if connect_socket() fails without doing any system calls
251 * which is only the case when forcing the IP family. So it is better to
252 * handle it in connect_socket(). */
253 connect_socket(socket
, connection_state(S_CONN
));
257 make_connection(struct socket
*socket
, struct uri
*uri
,
258 socket_connect_T connect_done
, int no_cache
)
260 unsigned char *host
= get_uri_string(uri
, URI_DNS_HOST
);
261 struct connect_info
*connect_info
;
262 enum dns_result result
;
264 socket
->ops
->set_timeout(socket
, connection_state(0));
267 socket
->ops
->retry(socket
, connection_state(S_OUT_OF_MEM
));
271 connect_info
= init_connection_info(uri
, socket
, connect_done
);
274 socket
->ops
->retry(socket
, connection_state(S_OUT_OF_MEM
));
278 socket
->connect_info
= connect_info
;
279 /* XXX: Keep here and not in init_connection_info() to make
280 * complete_connect_socket() work from the HTTP implementation. */
281 socket
->need_ssl
= get_protocol_need_ssl(uri
->protocol
);
282 if (!socket
->set_no_tls
) {
283 enum blacklist_flags flags
= get_blacklist_flags(uri
);
284 socket
->no_tls
= ((flags
& SERVER_BLACKLIST_NO_TLS
) != 0);
285 socket
->set_no_tls
= 1;
288 debug_transfer_log("\nCONNECTION: ", -1);
289 debug_transfer_log(host
, -1);
290 debug_transfer_log("\n", -1);
292 result
= find_host(host
, &connect_info
->dnsquery
, (dns_callback_T
) dns_found
,
297 if (result
== DNS_ASYNC
)
298 socket
->ops
->set_state(socket
, connection_state(S_DNS
));
302 /* Returns negative if error, otherwise pasv socket's fd. */
304 get_pasv_socket(struct socket
*ctrl_socket
, struct sockaddr_storage
*addr
)
306 struct sockaddr_in bind_addr4
;
307 struct sockaddr
*bind_addr
;
308 struct sockaddr
*pasv_addr
= (struct sockaddr
*) addr
;
311 int syspf
; /* Protocol Family given to system, not EL_PF_... */
314 struct sockaddr_in6 bind_addr6
;
316 if (ctrl_socket
->protocol_family
== EL_PF_INET6
) {
317 bind_addr
= (struct sockaddr
*) &bind_addr6
;
318 addrlen
= sizeof(bind_addr6
);
323 bind_addr
= (struct sockaddr
*) &bind_addr4
;
324 addrlen
= sizeof(bind_addr4
);
328 memset(pasv_addr
, 0, addrlen
);
329 memset(bind_addr
, 0, addrlen
);
331 /* Get our endpoint of the control socket */
333 if (getsockname(ctrl_socket
->fd
, pasv_addr
, &len
)) {
335 if (sock
!= -1) close(sock
);
336 ctrl_socket
->ops
->retry(ctrl_socket
,
337 connection_state_for_errno(errno
));
341 /* Get a passive socket */
343 sock
= socket(syspf
, SOCK_STREAM
, IPPROTO_TCP
);
347 /* Set it non-blocking */
349 if (set_nonblocking_fd(sock
) < 0)
352 /* Bind it to some port */
354 memcpy(bind_addr
, pasv_addr
, addrlen
);
356 if (ctrl_socket
->protocol_family
== EL_PF_INET6
)
357 bind_addr6
.sin6_port
= 0;
360 bind_addr4
.sin_port
= 0;
362 if (bind(sock
, bind_addr
, addrlen
))
365 /* Get our endpoint of the passive socket and save it to port */
368 if (getsockname(sock
, pasv_addr
, &len
))
376 set_ip_tos_throughput(sock
);
383 check_if_local_address6(struct sockaddr_in6
*addr
)
385 struct ifaddrs
*ifaddrs
;
386 int local
= IN6_IS_ADDR_LOOPBACK(&(addr
->sin6_addr
));
388 if (!local
&& !getifaddrs(&ifaddrs
)) {
391 for (ifa
= ifaddrs
; ifa
; ifa
= ifa
->ifa_next
) {
395 if (ifa
->ifa_addr
->sa_family
== AF_INET6
396 && !memcmp(&addr
->sin6_addr
.s6_addr
,
397 &((struct sockaddr_in6
*) ifa
->ifa_addr
)->sin6_addr
.s6_addr
,
398 sizeof(addr
->sin6_addr
.s6_addr
))) {
403 if (ifa
->ifa_addr
->sa_family
== AF_INET
404 && !memcmp(&((struct sockaddr_in
*) &addr
)->sin_addr
.s_addr
,
405 &((struct sockaddr_in
*) ifa
->ifa_addr
)->sin_addr
.s_addr
,
406 sizeof(((struct sockaddr_in
*) &addr
)->sin_addr
.s_addr
))) {
412 freeifaddrs(ifaddrs
);
417 #endif /* CONFIG_IPV6 */
420 check_if_local_address4(struct sockaddr_in
*addr
)
422 struct ifaddrs
*ifaddrs
;
423 int local
= (ntohl(addr
->sin_addr
.s_addr
) >> 24) == IN_LOOPBACKNET
;
425 if (!local
&& !getifaddrs(&ifaddrs
)) {
428 for (ifa
= ifaddrs
; ifa
; ifa
= ifa
->ifa_next
) {
432 if (ifa
->ifa_addr
->sa_family
!= AF_INET
) continue;
434 if (!memcmp(&addr
->sin_addr
.s_addr
,
435 &((struct sockaddr_in
*) ifa
->ifa_addr
)->sin_addr
.s_addr
,
436 sizeof(addr
->sin_addr
.s_addr
))) {
442 freeifaddrs(ifaddrs
);
450 complete_connect_socket(struct socket
*socket
, struct uri
*uri
,
451 socket_connect_T done
)
453 struct connect_info
*connect_info
= socket
->connect_info
;
455 if (connect_info
&& connect_info
->uri
) {
456 /* Remember whether the server supported TLS or not.
457 * Then the next request can immediately use the right
458 * protocol. This is important for HTTP POST requests
459 * because it is not safe to silently retry them. The
460 * uri parameter is normally NULL here so don't use it. */
462 add_blacklist_entry(connect_info
->uri
,
463 SERVER_BLACKLIST_NO_TLS
);
465 del_blacklist_entry(connect_info
->uri
,
466 SERVER_BLACKLIST_NO_TLS
);
469 /* This is a special case used by the HTTP implementation to acquire an
470 * SSL link for handling CONNECT requests. */
472 assert(uri
&& socket
);
473 connect_info
= init_connection_info(uri
, socket
, done
);
475 socket
->ops
->done(socket
, connection_state(S_OUT_OF_MEM
));
479 socket
->connect_info
= connect_info
;
483 /* Check if the connection should run over an encrypted link */
486 && ssl_connect(socket
) < 0)
490 if (connect_info
->done
)
491 connect_info
->done(socket
);
493 done_connection_info(socket
);
496 /* Select handler which is set for the socket descriptor when connect() has
497 * indicated (via errno) that it is in progress. On completion this handler gets
500 connected(struct socket
*socket
)
503 struct connection_state state
= connection_state(0);
504 socklen_t len
= sizeof(err
);
506 assertm(socket
->connect_info
!= NULL
, "Lost connect_info!");
507 if_assert_failed
return;
509 if (getsockopt(socket
->fd
, SOL_SOCKET
, SO_ERROR
, (void *) &err
, &len
) == 0) {
510 /* Why does EMX return so large values? */
511 if (err
>= 10000) err
-= 10000;
513 state
= connection_state_for_errno(err
);
515 state
= connection_state(0);
517 /* getsockopt() failed */
519 state
= connection_state_for_errno(errno
);
521 state
= connection_state(S_STATE
);
524 if (!is_in_state(state
, 0)) {
525 /* There are maybe still some more candidates. */
526 connect_socket(socket
, state
);
530 complete_connect_socket(socket
, NULL
, NULL
);
534 connect_socket(struct socket
*csocket
, struct connection_state state
)
537 struct connect_info
*connect_info
= csocket
->connect_info
;
539 int trno
= connect_info
->triedno
;
540 int only_local
= get_cmd_opt_bool("localhost");
542 int at_least_one_remote_ip
= 0;
544 int try_ipv6
= get_opt_bool("connection.try_ipv6", NULL
);
546 int try_ipv4
= get_opt_bool("connection.try_ipv4", NULL
);
547 /* We tried something but we failed in such a way that we would rather
548 * prefer the connection to retain the information about previous
549 * failures. That is, we i.e. decided we are forbidden to even think
550 * about such a connection attempt.
551 * XXX: Unify with @local_only handling? --pasky */
554 csocket
->ops
->set_state(csocket
, state
);
556 /* Clear handlers, the connection to the previous RR really timed
557 * out and doesn't interest us anymore. */
558 if (csocket
->fd
>= 0)
559 close_socket(csocket
);
561 for (i
= connect_info
->triedno
+ 1; i
< connect_info
->addrno
; i
++) {
563 struct sockaddr_in6 addr
= *((struct sockaddr_in6
*) &connect_info
->addr
[i
]);
564 int family
= addr
.sin6_family
;
566 struct sockaddr_in addr
= *((struct sockaddr_in
*) &connect_info
->addr
[i
]);
567 int family
= addr
.sin_family
;
570 int force_family
= connect_info
->ip_family
;
572 connect_info
->triedno
++;
577 if (family
== AF_INET6
)
578 local
= check_if_local_address6((struct sockaddr_in6
*) &addr
);
581 local
= check_if_local_address4((struct sockaddr_in
*) &addr
);
583 /* This forbids connections to anything but local, if option is set. */
585 at_least_one_remote_ip
= 1;
591 if (family
== AF_INET6
) {
592 if (!try_ipv6
|| (force_family
&& force_family
!= 6)) {
600 if (family
== AF_INET
) {
601 if (!try_ipv4
|| (force_family
&& force_family
!= 4)) {
612 sock
= socket(pf
, SOCK_STREAM
, IPPROTO_TCP
);
614 if (errno
&& !saved_errno
) saved_errno
= errno
;
618 if (set_nonblocking_fd(sock
) < 0) {
619 if (errno
&& !saved_errno
) saved_errno
= errno
;
626 addr
.sin6_port
= htons(connect_info
->port
);
628 addr
.sin_port
= htons(connect_info
->port
);
631 /* We can set csocket->protocol_family here even if the connection
632 * will fail, as we will use it only when it will be successfully
633 * established. At least I hope that noone else will want to do
634 * something else ;-). --pasky */
635 /* And in fact we must set it early, because of EINPROGRESS. */
638 if (family
== AF_INET6
) {
639 csocket
->protocol_family
= EL_PF_INET6
;
640 if (connect(sock
, (struct sockaddr
*) &addr
,
641 sizeof(struct sockaddr_in6
)) == 0) {
643 complete_connect_socket(csocket
, NULL
, NULL
);
649 csocket
->protocol_family
= EL_PF_INET
;
650 if (connect(sock
, (struct sockaddr
*) &addr
,
651 sizeof(struct sockaddr_in
)) == 0) {
653 complete_connect_socket(csocket
, NULL
, NULL
);
658 if (errno
== EALREADY
660 || errno
== EWOULDBLOCK
662 || errno
== EINPROGRESS
) {
663 /* It will take some more time... */
664 set_handlers(sock
, NULL
, (select_handler_T
) connected
,
665 (select_handler_T
) dns_exception
, csocket
);
666 csocket
->ops
->set_state(csocket
, connection_state(S_CONN
));
670 if (errno
&& !saved_errno
) saved_errno
= errno
;
675 assert(i
>= connect_info
->addrno
);
677 /* Tried everything, but it didn't help :(. */
679 if (only_local
&& !saved_errno
&& at_least_one_remote_ip
) {
680 /* Yes we might hit a local address and fail in the process, but
681 * what matters is the last one because we do not know the
682 * previous one's errno, and the added complexity wouldn't
683 * really be worth it. */
684 csocket
->ops
->done(csocket
, connection_state(S_LOCAL_ONLY
));
688 /* Retry reporting the errno state only if we already tried something
689 * new. Else use the S_DNS _progress_ state to make sure that no
690 * download callbacks will report any errors. */
691 if (trno
!= connect_info
->triedno
&& !silent_fail
)
692 state
= connection_state_for_errno(errno
);
693 else if (trno
== -1 && silent_fail
)
695 state
= connection_state(S_NO_FORCED_DNS
);
697 csocket
->ops
->retry(csocket
, state
);
701 struct write_buffer
{
702 /* A routine called when all the data is sent (therefore this is
703 * _different_ from read_buffer.done !). */
709 unsigned char data
[1]; /* must be at end of struct */
713 generic_write(struct socket
*socket
, unsigned char *data
, int len
)
715 int wr
= safe_write(socket
->fd
, data
, len
);
717 if (!wr
) return SOCKET_CANT_WRITE
;
719 return wr
< 0 ? SOCKET_SYSCALL_ERROR
: wr
;
723 write_select(struct socket
*socket
)
725 struct write_buffer
*wb
= socket
->write_buffer
;
728 assertm(wb
!= NULL
, "write socket has no buffer");
730 socket
->ops
->done(socket
, connection_state(S_INTERNAL
));
734 /* We are making some progress, therefore reset the timeout; ie. when
735 * uploading large files the time needed for all the data to be sent can
736 * easily exceed the timeout. */
737 socket
->ops
->set_timeout(socket
, connection_state(0));
740 printf("ws: %d\n",wb
->length
-wb
->pos
);
741 for (wr
= wb
->pos
; wr
< wb
->length
; wr
++) printf("%c", wb
->data
[wr
]);
747 wr
= ssl_write(socket
, wb
->data
+ wb
->pos
, wb
->length
- wb
->pos
);
751 assert(wb
->length
- wb
->pos
> 0);
752 wr
= generic_write(socket
, wb
->data
+ wb
->pos
, wb
->length
- wb
->pos
);
756 case SOCKET_CANT_WRITE
:
757 socket
->ops
->retry(socket
, connection_state(S_CANT_WRITE
));
760 case SOCKET_SYSCALL_ERROR
:
761 socket
->ops
->retry(socket
, connection_state_for_errno(errno
));
764 case SOCKET_INTERNAL_ERROR
:
765 /* The global errno variable is used for passing
766 * internal connection_state error value. */
767 socket
->ops
->done(socket
, connection_state(errno
));
773 /*printf("wr: %d\n", wr);*/
776 if (wb
->pos
== wb
->length
) {
777 socket_write_T done
= wb
->done
;
779 if (!socket
->duplex
) {
780 clear_handlers(socket
->fd
);
783 select_handler_T read_handler
;
784 select_handler_T error_handler
;
786 read_handler
= get_handler(socket
->fd
, SELECT_HANDLER_READ
);
787 error_handler
= read_handler
788 ? (select_handler_T
) exception
791 set_handlers(socket
->fd
, read_handler
, NULL
,
792 error_handler
, socket
);
795 mem_free_set(&socket
->write_buffer
, NULL
);
802 write_to_socket(struct socket
*socket
, unsigned char *data
, int len
,
803 struct connection_state state
, socket_write_T write_done
)
805 select_handler_T read_handler
;
806 struct write_buffer
*wb
;
808 debug_transfer_log(data
, len
);
811 if_assert_failed
return;
813 socket
->ops
->set_timeout(socket
, connection_state(0));
815 wb
= mem_alloc(sizeof(*wb
) + len
);
817 socket
->ops
->done(socket
, connection_state(S_OUT_OF_MEM
));
823 wb
->done
= write_done
;
824 memcpy(wb
->data
, data
, len
);
825 mem_free_set(&socket
->write_buffer
, wb
);
827 if (socket
->duplex
) {
828 read_handler
= get_handler(socket
->fd
, SELECT_HANDLER_READ
);
833 set_handlers(socket
->fd
, read_handler
, (select_handler_T
) write_select
,
834 (select_handler_T
) exception
, socket
);
835 socket
->ops
->set_state(socket
, state
);
838 #define RD_ALLOC_GR (2<<11) /* 4096 */
839 #define RD_MEM(rb) (sizeof(*(rb)) + 4 * RD_ALLOC_GR + RD_ALLOC_GR)
840 #define RD_SIZE(rb, len) ((RD_MEM(rb) + (len)) & ~(RD_ALLOC_GR - 1))
843 generic_read(struct socket
*socket
, unsigned char *data
, int len
)
845 ssize_t rd
= safe_read(socket
->fd
, data
, len
);
847 if (!rd
) return SOCKET_CANT_READ
;
849 return rd
< 0 ? SOCKET_SYSCALL_ERROR
: rd
;
853 read_select(struct socket
*socket
)
855 struct read_buffer
*rb
= socket
->read_buffer
;
858 assertm(rb
!= NULL
, "read socket has no buffer");
860 socket
->ops
->done(socket
, connection_state(S_INTERNAL
));
864 /* We are making some progress, therefore reset the timeout; we do this
865 * for read_select() to avoid that the periodic calls to user handlers
867 socket
->ops
->set_timeout(socket
, connection_state(0));
870 clear_handlers(socket
->fd
);
872 if (!rb
->freespace
) {
873 int size
= RD_SIZE(rb
, rb
->length
);
875 rb
= mem_realloc(rb
, size
);
877 socket
->ops
->done(socket
, connection_state(S_OUT_OF_MEM
));
880 rb
->freespace
= size
- sizeof(*rb
) - rb
->length
;
881 assert(rb
->freespace
> 0);
882 socket
->read_buffer
= rb
;
887 rd
= ssl_read(socket
, rb
->data
+ rb
->length
, rb
->freespace
);
891 rd
= generic_read(socket
, rb
->data
+ rb
->length
, rb
->freespace
);
896 case SOCKET_SSL_WANT_READ
:
897 read_from_socket(socket
, rb
, connection_state(S_TRANS
), rb
->done
);
900 case SOCKET_CANT_READ
:
901 if (socket
->state
!= SOCKET_RETRY_ONCLOSE
) {
902 socket
->state
= SOCKET_CLOSED
;
903 rb
->done(socket
, rb
);
907 socket
->ops
->retry(socket
, connection_state(S_CANT_READ
));
910 case SOCKET_SYSCALL_ERROR
:
911 socket
->ops
->retry(socket
, connection_state_for_errno(errno
));
914 case SOCKET_INTERNAL_ERROR
:
915 /* The global errno variable is used for passing
916 * internal connection_state error value. */
917 socket
->ops
->done(socket
, connection_state(errno
));
921 debug_transfer_log(rb
->data
+ rb
->length
, rd
);
925 assert(rb
->freespace
>= 0);
927 rb
->done(socket
, rb
);
932 alloc_read_buffer(struct socket
*socket
)
934 struct read_buffer
*rb
;
936 rb
= mem_calloc(1, RD_SIZE(rb
, 0));
938 socket
->ops
->done(socket
, connection_state(S_OUT_OF_MEM
));
942 rb
->freespace
= RD_SIZE(rb
, 0) - sizeof(*rb
);
952 read_from_socket(struct socket
*socket
, struct read_buffer
*buffer
,
953 struct connection_state state
, socket_read_T done
)
955 const int is_buffer_new
= (buffer
!= socket
->read_buffer
);
956 struct socket_weak_ref ref
;
957 select_handler_T write_handler
;
960 add_to_list(socket_weak_refs
, &ref
);
964 socket
->ops
->set_timeout(socket
, connection_state(0));
965 socket
->ops
->set_state(socket
, state
);
968 if (ref
.socket
== NULL
) {
969 /* socket->ops->set_state deleted the socket. */
975 if (socket
->read_buffer
&& buffer
!= socket
->read_buffer
)
976 mem_free(socket
->read_buffer
);
977 socket
->read_buffer
= buffer
;
979 if (socket
->duplex
) {
980 write_handler
= get_handler(socket
->fd
, SELECT_HANDLER_WRITE
);
982 write_handler
= NULL
;
985 set_handlers(socket
->fd
, (select_handler_T
) read_select
, write_handler
,
986 (select_handler_T
) exception
, socket
);
990 read_response_from_socket(struct socket
*socket
)
992 struct read_buffer
*rb
= alloc_read_buffer(socket
);
994 if (rb
) read_from_socket(socket
, rb
, connection_state(S_SENT
),
999 request_from_socket(struct socket
*socket
, unsigned char *data
, int datalen
,
1000 struct connection_state state
, enum socket_state sock_state
,
1001 socket_read_T read_done
)
1003 socket
->read_done
= read_done
;
1004 socket
->state
= sock_state
;
1005 write_to_socket(socket
, data
, datalen
, state
,
1006 read_response_from_socket
);
1010 kill_buffer_data(struct read_buffer
*rb
, int n
)
1012 assertm(n
>= 0 && n
<= rb
->length
, "bad number of bytes: %d", n
);
1013 if_assert_failed
{ rb
->length
= 0; return; }
1015 if (!n
) return; /* FIXME: We accept to kill 0 bytes... */
1017 memmove(rb
->data
, rb
->data
+ n
, rb
->length
);