00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <errno.h>
00024 #include <fcntl.h>
00025 #include <limits.h>
00026 #include <netdb.h>
00027 #include <poll.h>
00028 #include <signal.h>
00029 #include <stddef.h>
00030 #include <stdint.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <time.h>
00035 #include <unistd.h>
00036 #include <arpa/inet.h>
00037 #include <sys/time.h>
00038 #include <sys/socket.h>
00039 #include <sys/stat.h>
00040 #include <sys/types.h>
00041 #include <sys/un.h>
00042 #include <netinet/in.h>
00043
00044 #include <ccn/bloom.h>
00045 #include <ccn/ccn.h>
00046 #include <ccn/ccn_private.h>
00047 #include <ccn/charbuf.h>
00048 #include <ccn/face_mgmt.h>
00049 #include <ccn/hashtb.h>
00050 #include <ccn/indexbuf.h>
00051 #include <ccn/schedule.h>
00052 #include <ccn/reg_mgmt.h>
00053 #include <ccn/uri.h>
00054
00055 #include <sync/SyncBase.h>
00056
00057 #include "ccnr_private.h"
00058
00059 #include "ccnr_dispatch.h"
00060
00061 #include "ccnr_forwarding.h"
00062 #include "ccnr_io.h"
00063 #include "ccnr_link.h"
00064 #include "ccnr_match.h"
00065 #include "ccnr_msg.h"
00066 #include "ccnr_proto.h"
00067 #include "ccnr_sendq.h"
00068 #include "ccnr_stats.h"
00069 #include "ccnr_store.h"
00070 #include "ccnr_sync.h"
00071 #include "ccnr_util.h"
00072
00073 static void
00074 process_input_message(struct ccnr_handle *h, struct fdholder *fdholder,
00075 unsigned char *msg, size_t size, int pdu_ok,
00076 off_t *offsetp)
00077 {
00078 struct ccn_skeleton_decoder decoder = {0};
00079 struct ccn_skeleton_decoder *d = &decoder;
00080 ssize_t dres;
00081 enum ccn_dtag dtag;
00082 struct content_entry *content = NULL;
00083
00084 if ((fdholder->flags & CCNR_FACE_UNDECIDED) != 0) {
00085 fdholder->flags &= ~CCNR_FACE_UNDECIDED;
00086 if ((fdholder->flags & CCNR_FACE_LOOPBACK) != 0)
00087 fdholder->flags |= CCNR_FACE_GG;
00088
00089 r_io_register_new_face(h, fdholder);
00090 }
00091 d->state |= CCN_DSTATE_PAUSE;
00092 dres = ccn_skeleton_decode(d, msg, size);
00093 if (d->state < 0)
00094 abort();
00095 if (CCN_GET_TT_FROM_DSTATE(d->state) != CCN_DTAG) {
00096 ccnr_msg(h, "discarding unknown message; size = %lu", (unsigned long)size);
00097
00098 return;
00099 }
00100 dtag = d->numval;
00101 switch (dtag) {
00102
00103
00104
00105 case CCN_DTAG_ContentObject:
00106 content = process_incoming_content(h, fdholder, msg, size);
00107 if (content != NULL && offsetp != NULL)
00108 r_store_set_accession_from_offset(h, content, fdholder, *offsetp);
00109 return;
00110 default:
00111 break;
00112 }
00113 ccnr_msg(h, "discarding unknown message; dtag=%u, size = %lu",
00114 (unsigned)dtag,
00115 (unsigned long)size);
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125 static void
00126 process_input_buffer(struct ccnr_handle *h, struct fdholder *fdholder)
00127 {
00128 unsigned char *msg;
00129 size_t size;
00130 ssize_t dres;
00131 struct ccn_skeleton_decoder *d;
00132
00133 if (fdholder == NULL || fdholder->inbuf == NULL)
00134 return;
00135 d = &fdholder->decoder;
00136 msg = fdholder->inbuf->buf;
00137 size = fdholder->inbuf->length;
00138 while (d->index < size) {
00139 dres = ccn_skeleton_decode(d, msg + d->index, size - d->index);
00140 if (d->state != 0)
00141 break;
00142 process_input_message(h, fdholder, msg + d->index - dres, dres, 0, NULL);
00143 }
00144 if (d->index != size) {
00145 ccnr_msg(h, "protocol error on fdholder %u (state %d), discarding %d bytes",
00146 fdholder->filedesc, d->state, (int)(size - d->index));
00147
00148 }
00149 fdholder->inbuf->length = 0;
00150 memset(d, 0, sizeof(*d));
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 PUBLIC void
00162 r_dispatch_process_input(struct ccnr_handle *h, int fd)
00163 {
00164 struct fdholder *fdholder = NULL;
00165 struct fdholder *source = NULL;
00166 ssize_t res;
00167 ssize_t dres;
00168 ssize_t msgstart;
00169 unsigned char *buf;
00170 struct ccn_skeleton_decoder *d;
00171 struct sockaddr_storage sstor;
00172 socklen_t addrlen = sizeof(sstor);
00173 struct sockaddr *addr = (struct sockaddr *)&sstor;
00174
00175 fdholder = r_io_fdholder_from_fd(h, fd);
00176 if (fdholder == NULL)
00177 return;
00178 if ((fdholder->flags & (CCNR_FACE_DGRAM | CCNR_FACE_PASSIVE)) == CCNR_FACE_PASSIVE) {
00179 r_io_accept_connection(h, fd);
00180 return;
00181 }
00182 if ((fdholder->flags & CCNR_FACE_CCND) != 0) {
00183 res = ccn_run(h->direct_client, 0);
00184 if (res < 0) {
00185
00186
00187 ccnr_msg(h, "ccn_run returned error, shutting down direct client");
00188 r_io_shutdown_client_fd(h, fd);
00189 }
00190 return;
00191 }
00192 d = &fdholder->decoder;
00193 if (fdholder->inbuf == NULL) {
00194 fdholder->inbuf = ccn_charbuf_create();
00195 fdholder->bufoffset = 0;
00196 }
00197 if (fdholder->inbuf->length == 0)
00198 memset(d, 0, sizeof(*d));
00199 buf = ccn_charbuf_reserve(fdholder->inbuf, 8800);
00200 memset(&sstor, 0, sizeof(sstor));
00201 if ((fdholder->flags & CCNR_FACE_SOCKMASK) != 0) {
00202 res = recvfrom(fdholder->filedesc, buf, fdholder->inbuf->limit - fdholder->inbuf->length,
00203 0, addr, &addrlen);
00204 }
00205 else {
00206 res = read(fdholder->filedesc, buf, fdholder->inbuf->limit - fdholder->inbuf->length);
00207 }
00208 if (res == -1)
00209 ccnr_msg(h, "read %u :%s (errno = %d)",
00210 fdholder->filedesc, strerror(errno), errno);
00211 else if (res == 0 && (fdholder->flags & CCNR_FACE_DGRAM) == 0) {
00212 if (fd == h->active_in_fd && h->stable == 0) {
00213 h->stable = lseek(fd, 0, SEEK_END);
00214 ccnr_msg(h, "read %ju bytes", (uintmax_t)h->stable);
00215 }
00216 r_io_shutdown_client_fd(h, fd);
00217 }
00218 else {
00219 off_t offset = (off_t)-1;
00220 off_t *offsetp = NULL;
00221 if ((fdholder->flags & CCNR_FACE_REPODATA) != 0)
00222 offsetp = &offset;
00223 source = fdholder;
00224 ccnr_meter_bump(h, source->meter[FM_BYTI], res);
00225 source->recvcount++;
00226 fdholder->inbuf->length += res;
00227 msgstart = 0;
00228 if ((fdholder->flags & CCNR_FACE_UNDECIDED) != 0) {
00229 ccnr_stats_handle_http_connection(h, fdholder);
00230 return;
00231 }
00232 dres = ccn_skeleton_decode(d, buf, res);
00233 while (d->state == 0) {
00234 if (offsetp != NULL)
00235 *offsetp = fdholder->bufoffset + msgstart;
00236 process_input_message(h, source,
00237 fdholder->inbuf->buf + msgstart,
00238 d->index - msgstart,
00239 (fdholder->flags & CCNR_FACE_LOCAL) != 0,
00240 offsetp);
00241 msgstart = d->index;
00242 if (msgstart == fdholder->inbuf->length) {
00243 fdholder->inbuf->length = 0;
00244 fdholder->bufoffset += msgstart;
00245 return;
00246 }
00247 dres = ccn_skeleton_decode(d,
00248 fdholder->inbuf->buf + msgstart,
00249 fdholder->inbuf->length - msgstart);
00250 }
00251 fdholder->bufoffset += msgstart;
00252 if ((fdholder->flags & CCNR_FACE_DGRAM) != 0) {
00253 ccnr_msg(h, "protocol error on fdholder %u, discarding %u bytes",
00254 source->filedesc,
00255 (unsigned)(fdholder->inbuf->length - msgstart));
00256 fdholder->inbuf->length = 0;
00257
00258 return;
00259 }
00260 else if (d->state < 0) {
00261 ccnr_msg(h, "protocol error on fdholder %u", source->filedesc);
00262 r_io_shutdown_client_fd(h, fd);
00263 return;
00264 }
00265 if (msgstart < fdholder->inbuf->length && msgstart > 0) {
00266
00267 memmove(fdholder->inbuf->buf, fdholder->inbuf->buf + msgstart,
00268 fdholder->inbuf->length - msgstart);
00269 fdholder->inbuf->length -= msgstart;
00270 d->index -= msgstart;
00271 }
00272 }
00273 }
00274
00275 PUBLIC void
00276 r_dispatch_process_internal_client_buffer(struct ccnr_handle *h)
00277 {
00278 struct fdholder *fdholder = h->face0;
00279 if (fdholder == NULL)
00280 return;
00281 fdholder->inbuf = ccn_grab_buffered_output(h->internal_client);
00282 if (fdholder->inbuf == NULL)
00283 return;
00284 ccnr_meter_bump(h, fdholder->meter[FM_BYTI], fdholder->inbuf->length);
00285 process_input_buffer(h, fdholder);
00286 ccn_charbuf_destroy(&(fdholder->inbuf));
00287 }
00288
00289
00290
00291 PUBLIC void
00292 r_dispatch_run(struct ccnr_handle *h)
00293 {
00294 int i;
00295 int res;
00296 int timeout_ms = -1;
00297 int prev_timeout_ms = -1;
00298 int usec;
00299 int usec_direct;
00300
00301 if (h->running < 0) {
00302 ccnr_msg(h, "Fatal error during initialization");
00303 return;
00304 }
00305 for (h->running = 1; h->running;) {
00306 r_dispatch_process_internal_client_buffer(h);
00307 usec = ccn_schedule_run(h->sched);
00308 usec_direct = ccn_process_scheduled_operations(h->direct_client);
00309 if (usec_direct < usec)
00310 usec = usec_direct;
00311 if (1) {
00312
00313 if (ccn_get_connection_fd(h->direct_client) == -1) {
00314
00315 ccnr_msg(h, "lost connection to ccnd");
00316 h->running = 0;
00317 break;
00318 }
00319 }
00320 timeout_ms = (usec < 0) ? -1 : ((usec + 960) / 1000);
00321 if (timeout_ms == 0 && prev_timeout_ms == 0)
00322 timeout_ms = 1;
00323 r_dispatch_process_internal_client_buffer(h);
00324 r_store_trim(h, h->cob_limit);
00325 r_io_prepare_poll_fds(h);
00326 res = poll(h->fds, h->nfds, timeout_ms);
00327 prev_timeout_ms = ((res == 0) ? timeout_ms : 1);
00328 if (-1 == res) {
00329 if (errno == EINTR)
00330 continue;
00331 ccnr_msg(h, "poll: %s (errno = %d)", strerror(errno), errno);
00332 sleep(1);
00333 continue;
00334 }
00335 for (i = 0; res > 0 && i < h->nfds; i++) {
00336 if (h->fds[i].revents != 0) {
00337 res--;
00338 if (h->fds[i].revents & (POLLERR | POLLNVAL | POLLHUP)) {
00339 if (h->fds[i].revents & (POLLIN))
00340 r_dispatch_process_input(h, h->fds[i].fd);
00341 else
00342 r_io_shutdown_client_fd(h, h->fds[i].fd);
00343 continue;
00344 }
00345 if (h->fds[i].revents & (POLLOUT))
00346 r_link_do_deferred_write(h, h->fds[i].fd);
00347 else if (h->fds[i].revents & (POLLIN))
00348 r_dispatch_process_input(h, h->fds[i].fd);
00349 else
00350 ccnr_msg(h, "poll: UNHANDLED");
00351 }
00352 }
00353 }
00354 }