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, offsetp);
00107 if (content != NULL)
00108 r_store_commit_content(h, content);
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 fdholder->inbuf->length >= 6 &&
00230 0 == memcmp(fdholder->inbuf->buf, "GET ", 4))) {
00231 ccnr_stats_handle_http_connection(h, fdholder);
00232 return;
00233 }
00234 dres = ccn_skeleton_decode(d, buf, res);
00235 while (d->state == 0) {
00236 if (offsetp != NULL)
00237 *offsetp = fdholder->bufoffset + msgstart;
00238 process_input_message(h, source,
00239 fdholder->inbuf->buf + msgstart,
00240 d->index - msgstart,
00241 (fdholder->flags & CCNR_FACE_LOCAL) != 0,
00242 offsetp);
00243 msgstart = d->index;
00244 if (msgstart == fdholder->inbuf->length) {
00245 fdholder->inbuf->length = 0;
00246 fdholder->bufoffset += msgstart;
00247 return;
00248 }
00249 dres = ccn_skeleton_decode(d,
00250 fdholder->inbuf->buf + msgstart,
00251 fdholder->inbuf->length - msgstart);
00252 }
00253 fdholder->bufoffset += msgstart;
00254 if ((fdholder->flags & CCNR_FACE_DGRAM) != 0) {
00255 ccnr_msg(h, "protocol error on fdholder %u, discarding %u bytes",
00256 source->filedesc,
00257 (unsigned)(fdholder->inbuf->length - msgstart));
00258 fdholder->inbuf->length = 0;
00259
00260 return;
00261 }
00262 else if (d->state < 0) {
00263 ccnr_msg(h, "protocol error on fdholder %u", source->filedesc);
00264 r_io_shutdown_client_fd(h, fd);
00265 return;
00266 }
00267 if (msgstart < fdholder->inbuf->length && msgstart > 0) {
00268
00269 memmove(fdholder->inbuf->buf, fdholder->inbuf->buf + msgstart,
00270 fdholder->inbuf->length - msgstart);
00271 fdholder->inbuf->length -= msgstart;
00272 d->index -= msgstart;
00273 }
00274 }
00275 }
00276
00277 PUBLIC void
00278 r_dispatch_process_internal_client_buffer(struct ccnr_handle *h)
00279 {
00280 struct fdholder *fdholder = h->face0;
00281 if (fdholder == NULL)
00282 return;
00283 fdholder->inbuf = ccn_grab_buffered_output(h->internal_client);
00284 if (fdholder->inbuf == NULL)
00285 return;
00286 ccnr_meter_bump(h, fdholder->meter[FM_BYTI], fdholder->inbuf->length);
00287 process_input_buffer(h, fdholder);
00288 ccn_charbuf_destroy(&(fdholder->inbuf));
00289 }
00290
00291
00292
00293 PUBLIC void
00294 r_dispatch_run(struct ccnr_handle *h)
00295 {
00296 int i;
00297 int res;
00298 int timeout_ms = -1;
00299 int prev_timeout_ms = -1;
00300 int usec;
00301 int usec_direct;
00302
00303 if (h->running < 0) {
00304 ccnr_msg(h, "Fatal error during initialization");
00305 return;
00306 }
00307 for (h->running = 1; h->running;) {
00308 r_dispatch_process_internal_client_buffer(h);
00309 usec = ccn_schedule_run(h->sched);
00310 usec_direct = ccn_process_scheduled_operations(h->direct_client);
00311 if (usec_direct < usec)
00312 usec = usec_direct;
00313 if (1) {
00314
00315 if (ccn_get_connection_fd(h->direct_client) == -1) {
00316
00317 ccnr_msg(h, "lost connection to ccnd");
00318 h->running = 0;
00319 break;
00320 }
00321 }
00322 timeout_ms = (usec < 0) ? -1 : ((usec + 960) / 1000);
00323 if (timeout_ms == 0 && prev_timeout_ms == 0)
00324 timeout_ms = 1;
00325 r_dispatch_process_internal_client_buffer(h);
00326 r_store_trim(h, h->cob_limit);
00327 r_io_prepare_poll_fds(h);
00328 res = poll(h->fds, h->nfds, timeout_ms);
00329 prev_timeout_ms = ((res == 0) ? timeout_ms : 1);
00330 if (-1 == res) {
00331 if (errno == EINTR)
00332 continue;
00333 ccnr_msg(h, "poll: %s (errno = %d)", strerror(errno), errno);
00334 sleep(1);
00335 continue;
00336 }
00337 for (i = 0; res > 0 && i < h->nfds; i++) {
00338 if (h->fds[i].revents != 0) {
00339 res--;
00340 if (h->fds[i].revents & (POLLERR | POLLNVAL | POLLHUP)) {
00341 if (h->fds[i].revents & (POLLIN))
00342 r_dispatch_process_input(h, h->fds[i].fd);
00343 else
00344 r_io_shutdown_client_fd(h, h->fds[i].fd);
00345 continue;
00346 }
00347 if (h->fds[i].revents & (POLLOUT))
00348 r_link_do_deferred_write(h, h->fds[i].fd);
00349 else if (h->fds[i].revents & (POLLIN))
00350 r_dispatch_process_input(h, h->fds[i].fd);
00351 else
00352 ccnr_msg(h, "poll: UNHANDLED");
00353 }
00354 }
00355 }
00356 }