00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <errno.h>
00026 #include <fcntl.h>
00027 #include <limits.h>
00028 #include <netdb.h>
00029 #include <poll.h>
00030 #include <signal.h>
00031 #include <stddef.h>
00032 #include <stdint.h>
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036 #include <time.h>
00037 #include <unistd.h>
00038 #include <arpa/inet.h>
00039 #include <sys/time.h>
00040 #include <sys/socket.h>
00041 #include <sys/stat.h>
00042 #include <sys/types.h>
00043 #include <sys/un.h>
00044 #include <netinet/in.h>
00045
00046 #include <ccn/bloom.h>
00047 #include <ccn/ccn.h>
00048 #include <ccn/ccn_private.h>
00049 #include <ccn/charbuf.h>
00050 #include <ccn/face_mgmt.h>
00051 #include <ccn/hashtb.h>
00052 #include <ccn/indexbuf.h>
00053 #include <ccn/schedule.h>
00054 #include <ccn/reg_mgmt.h>
00055 #include <ccn/uri.h>
00056
00057 #include "ccnr_private.h"
00058
00059 #include "ccnr_link.h"
00060
00061 #include "ccnr_forwarding.h"
00062 #include "ccnr_internal_client.h"
00063 #include "ccnr_io.h"
00064 #include "ccnr_link.h"
00065 #include "ccnr_match.h"
00066 #include "ccnr_msg.h"
00067 #include "ccnr_sendq.h"
00068 #include "ccnr_stats.h"
00069 #include "ccnr_store.h"
00070 #include "ccnr_util.h"
00071
00072 PUBLIC void
00073 r_link_send_content(struct ccnr_handle *h, struct fdholder *fdholder, struct content_entry *content)
00074 {
00075 if ((fdholder->flags & CCNR_FACE_NOSEND) != 0) {
00076
00077 return;
00078 }
00079 r_store_send_content(h, fdholder, content);
00080 ccnr_meter_bump(h, fdholder->meter[FM_DATO], 1);
00081 h->content_items_sent += 1;
00082 }
00083
00084
00085
00086
00087 PUBLIC void
00088 r_link_stuff_and_send(struct ccnr_handle *h, struct fdholder *fdholder,
00089 const unsigned char *data1, size_t size1,
00090 const unsigned char *data2, size_t size2,
00091 off_t *offsetp) {
00092 struct ccn_charbuf *c = NULL;
00093
00094 if (size2 != 0 || 1 > size1 + size2) {
00095 c = r_util_charbuf_obtain(h);
00096 ccn_charbuf_append(c, data1, size1);
00097 if (size2 != 0)
00098 ccn_charbuf_append(c, data2, size2);
00099 }
00100 else {
00101
00102 r_io_send(h, fdholder, data1, size1, offsetp);
00103 return;
00104 }
00105 r_io_send(h, fdholder, c->buf, c->length, offsetp);
00106 r_util_charbuf_release(h, c);
00107 return;
00108 }
00109
00110 PUBLIC void
00111 r_link_do_deferred_write(struct ccnr_handle *h, int fd)
00112 {
00113
00114 ssize_t res;
00115 struct fdholder *fdholder = r_io_fdholder_from_fd(h, fd);
00116 if (fdholder == NULL)
00117 return;
00118 if ((fdholder->flags & CCNR_FACE_CCND) != 0) {
00119
00120 if (CCNSHOULDLOG(h, xxx, CCNL_FINE))
00121 ccnr_msg(h, "sending deferred output from direct client");
00122 ccn_run(h->direct_client, 0);
00123 if (fdholder->outbuf != NULL)
00124 ccnr_msg(h, "URP r_link_do_deferred_write %d", __LINE__);
00125 return;
00126 }
00127 if (fdholder->outbuf != NULL) {
00128 ssize_t sendlen = fdholder->outbuf->length - fdholder->outbufindex;
00129 if (sendlen > 0) {
00130 res = send(fd, fdholder->outbuf->buf + fdholder->outbufindex, sendlen, 0);
00131 if (res == -1) {
00132 if (errno == EPIPE) {
00133 fdholder->flags |= CCNR_FACE_NOSEND;
00134 fdholder->outbufindex = 0;
00135 ccn_charbuf_destroy(&fdholder->outbuf);
00136 return;
00137 }
00138 ccnr_msg(h, "send: %s (errno = %d)", strerror(errno), errno);
00139 r_io_shutdown_client_fd(h, fd);
00140 return;
00141 }
00142 if (res == sendlen) {
00143 fdholder->outbufindex = 0;
00144 ccn_charbuf_destroy(&fdholder->outbuf);
00145 if ((fdholder->flags & CCNR_FACE_CLOSING) != 0)
00146 r_io_shutdown_client_fd(h, fd);
00147 return;
00148 }
00149 fdholder->outbufindex += res;
00150 return;
00151 }
00152 fdholder->outbufindex = 0;
00153 ccn_charbuf_destroy(&fdholder->outbuf);
00154 }
00155 if ((fdholder->flags & CCNR_FACE_CLOSING) != 0)
00156 r_io_shutdown_client_fd(h, fd);
00157 else if ((fdholder->flags & CCNR_FACE_CONNECTING) != 0) {
00158 fdholder->flags &= ~CCNR_FACE_CONNECTING;
00159 ccnr_face_status_change(h, fdholder->filedesc);
00160 }
00161 else
00162 ccnr_msg(h, "ccnr:r_link_do_deferred_write: something fishy on %d", fd);
00163 }