ccnr_link.c

Go to the documentation of this file.
00001 /**
00002  * @file ccnr_link.c
00003  * 
00004  * Part of ccnr -  CCNx Repository Daemon.
00005  *
00006  */
00007 
00008 /*
00009  * Copyright (C) 2011 Palo Alto Research Center, Inc.
00010  *
00011  * This work is free software; you can redistribute it and/or modify it under
00012  * the terms of the GNU General Public License version 2 as published by the
00013  * Free Software Foundation.
00014  * This work is distributed in the hope that it will be useful, but WITHOUT ANY
00015  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00016  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
00017  * for more details. You should have received a copy of the GNU General Public
00018  * License along with this program; if not, write to the
00019  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  * Boston, MA 02110-1301, USA.
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         // XXX - should count this.
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  * Send a message, which may be in two pieces.
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         /* avoid a copy in this case */
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     /* This only happens on connected sockets */
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         /* The direct client has something to say. */
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 }

Generated on Thu Feb 16 00:43:58 2012 for Content-Centric Networking in C by  doxygen 1.5.6