Ejemplo n.º 1
0
/* set send/receive timeouts on socket(s)
 */
int
set_timeouts( int rsock, int ssock,
              u_short rcv_tmout_sec, u_short rcv_tmout_usec,
              u_short snd_tmout_sec, u_short snd_tmout_usec )
{
    struct timeval rtv, stv;
    int rc = 0;

    if( rsock ) {
        rtv.tv_sec = rcv_tmout_sec;
        rtv.tv_usec = rcv_tmout_usec;
        rc = setsockopt( rsock, SOL_SOCKET, SO_RCVTIMEO, &rtv, sizeof(rtv) );
        if( -1 == rc ) {
            mperror(g_flog, errno, "%s: setsockopt - SO_RCVTIMEO",
                    __func__);
            return ERR_INTERNAL;
        }
        TRACE( (void)tmfprintf (g_flog, "socket %d: RCV timeout set to %ld sec, %ld usec\n",
                rsock, rtv.tv_sec, rtv.tv_usec) );
    }

    if( ssock ) {
        stv.tv_sec = snd_tmout_sec;
        stv.tv_usec = snd_tmout_usec;
        rc = setsockopt( ssock, SOL_SOCKET, SO_SNDTIMEO, &stv, sizeof(stv) );
        if( -1 == rc ) {
            mperror(g_flog, errno, "%s: setsockopt - SO_SNDTIMEO", __func__);
            return ERR_INTERNAL;
        }
        TRACE( (void)tmfprintf (g_flog, "socket %d: SEND timeout set to %ld sec, %ld usec\n",
                rsock, rtv.tv_sec, rtv.tv_usec) );
    }

    return rc;
}
Ejemplo n.º 2
0
/* subscribe to the (configured) multicast channel
 */
static int
subscribe( int* sockfd, struct in_addr* mcast_inaddr )
{
    struct sockaddr_in sa;
    const char* ipaddr = g_recopt.rec_channel;
    size_t rcvbuf_len = 0;
    int rc = 0;

    assert( sockfd && mcast_inaddr );

    if( 1 != inet_aton( ipaddr, &sa.sin_addr ) ) {
        mperror( g_flog, errno,
                "%s: Invalid subscription [%s:%d]: inet_aton",
                __func__, ipaddr, g_recopt.rec_port );
        return -1;
    }

    sa.sin_family = AF_INET;
    sa.sin_port = htons( (uint16_t)g_recopt.rec_port );

    if( 1 != inet_aton( g_recopt.mcast_addr, mcast_inaddr ) ) {
        mperror( g_flog, errno,
                "%s: Invalid multicast interface: [%s]: inet_aton",
                __func__, g_recopt.mcast_addr );
        return -1;
    }

    rc = calc_buf_settings( NULL, &rcvbuf_len );
    if (0 != rc) return rc;

    return setup_mcast_listener( &sa, mcast_inaddr,
            sockfd, (g_recopt.nosync_sbuf ? 0 : rcvbuf_len) );
}
Ejemplo n.º 3
0
/* set/clear file/socket's mode as non-blocking
 */
int
set_nblock( int fd, int set )
{
    int flags = 0;

    flags = fcntl( fd, F_GETFL, 0 );
    if( flags < 0 ) {
        mperror( g_flog, errno, "%s: fcntl() getting flags on fd=[%d]",
                    __func__, fd );
        return -1;
    }

    if( set )
        flags |= O_NONBLOCK;
    else
        flags &= ~O_NONBLOCK;

    if( fcntl( fd, F_SETFL, flags ) < 0 ) {
        mperror( g_flog, errno, "%s: fcntl() %s non-blocking mode "
                "on fd=[%d]", __func__, (set ? "setting" : "clearing"),
                fd );
        return -1;
    }

    return 0;
}
Ejemplo n.º 4
0
/* ---------------- file_no_cache -----------------------------
 * When we read sequentially from a huge series of structure
 * files, the OS tries to cache them all, although we will not
 * reuse them in the near future.
 * This is not harmless. When running in the background, wurst
 * tends to fill the cache with this data, wipe out files that a
 * user really does want to work with.
 * This is a wrapper around the posix routine which should be
 * called on all files like this (structures, profiles, ...).
 * The routine may not be provided everywhere, so put any
 * portability checks in here.
 * To be sure, maybe I should also call the function
 * with POSIX_FADV_DONTNEED.
 * Return
 *  0 if all went well
 *  errno if something broke.
 */
int
file_no_cache (FILE *fp)
{
#   ifdef POSIX_FADV_SEQUENTIAL
        int fnum, r, s;
        struct stat statbuf;
        const off_t offset = 0;
        const size_t len = 0;
        const char *this_sub = "file_no_cache";
        int e = 0; 
        if ((fnum = fileno (fp)) == -1) {
            mperror (this_sub);
            return ( -1 );
        }
        if (fstat ( fnum, &statbuf) == -1) {
            mperror (this_sub);
            return ( -1 );
        }

        if ( S_ISFIFO (statbuf.st_mode))         /* If this is a pipe,*/
            return 0;                            /* then just return  */

        if ((r = posix_fadvise (fnum, offset, len, POSIX_FADV_SEQUENTIAL))) {
            e = errno;
            err_printf (this_sub, "POSIX_FADV_SEQUENTIAL probably broken.\n");
        }
        if ((s = posix_fadvise (fnum, offset, len, POSIX_FADV_NOREUSE))) {
            e = errno;
            err_printf (this_sub, "POSIX_FADV_NOREUSE probably broken.\n");
        }
        if (r != 0 || s!= 0)
            return e;
#   endif   /* POSIX_FADV_SEQUENTIAL */
        return 0;
}
Ejemplo n.º 5
0
/* read HTTP request from sockfd, parse it into command
 * and its parameters (for instance, command='udp' and
 * parameters being '192.168.0.1:5002')
 */
static int
read_command( int sockfd, struct server_ctx *srv)
{
#define DBUF_SZ 2048  /* max size for raw data with HTTP request */
#define RBUF_SZ 512   /* max size for url-derived request */
    char httpbuf[ DBUF_SZ ] = "\0", request[ RBUF_SZ ] = "\0";
    ssize_t hlen;
    size_t  rlen;
    int rc = 0;

    assert( (sockfd > 0) && srv );

    TRACE( (void)tmfprintf( g_flog,  "Reading command from socket [%d]\n",
                            sockfd ) );
usleep(50);  /* ..workaround VLC behavior: wait for receiving entire HTTP request, one packet per line */
    hlen = recv( sockfd, httpbuf, sizeof(httpbuf), 0 );
    if( 0>hlen ) {
        rc = errno;
        if( !no_fault(rc) )
            mperror(g_flog, rc, "%s - recv (%d)", __func__, rc);
        else {
            TRACE( mperror(g_flog, rc, "%s - recv (%d)", __func__, rc) );
        }
        return rc;
    }
    if (0 == hlen) {
        (void) tmfprintf (g_flog, "%s: client closed socket [%d]\n",
            __func__, sockfd);
        return 1;
    }

    /* DEBUG - re-enable if needed */
    TRACE( (void)tmfprintf( g_flog, "HTTP buffer [%ld bytes] received\n%s", (long)hlen, httpbuf ) );
    /* TRACE( (void) save_buffer( httpbuf, hlen, "/tmp/httpbuf.dat" ) ); */

    rlen = sizeof(request);
    rc = get_request( httpbuf, (size_t)hlen, request, &rlen );
    if (rc) return rc;

    TRACE( (void)tmfprintf( g_flog, "Request=[%s], length=[%lu]\n",
                request, (u_long)rlen ) );

    rc = parse_auth( httpbuf, (size_t)hlen );
    TRACE( (void)tmfprintf( g_flog, "Auth result=[%d]\n",
                rc ) );
    if (rc) return rc;

    (void) memset( &srv->rq, 0, sizeof(srv->rq) );
    rc = parse_param( request, rlen, srv->rq.cmd, sizeof(srv->rq.cmd),
                srv->rq.param, sizeof(srv->rq.param),
                srv->rq.tail, sizeof(srv->rq.tail) );
    if( 0 == rc ) {
        TRACE( (void)tmfprintf( g_flog, "Command [%s] with params [%s], tail [%s]"
                    " read from socket=[%d]\n", srv->rq.cmd, srv->rq.param,
                        srv->rq.tail, sockfd) );
    }

    return rc;
}
Ejemplo n.º 6
0
/* send server status as HTTP response to the given socket
 */
static int
report_status( int sockfd, const struct server_ctx* ctx, int options )
{
    char *buf = NULL;
    int rc = 0;
    ssize_t n, nsent;
    size_t nlen = 0, bufsz, i;
    struct client_ctx *clc = NULL;

    enum {BYTES_HDR = 2048, BYTES_PER_CLI = 256};

    assert( (sockfd > 0) && ctx );

    bufsz = BYTES_HDR;
    for (i = 0, clc=ctx->cl; i < ctx->clmax; ++i, ++clc) {
        if( ctx->cl[i].pid > 0 )
            bufsz += BYTES_PER_CLI + strlen(clc->tail);
    }

    buf = malloc(bufsz);
    if( !buf ) {
        mperror(g_flog, ENOMEM, "malloc for %ld bytes for HTTP buffer "
            "failed in %s", (long)bufsz, __func__ );
        return ERR_INTERNAL;
    }

    (void) memset( buf, 0, sizeof(bufsz) );

    nlen = bufsz;
    rc = mk_status_page( ctx, buf, &nlen, options | MSO_HTTP_HEADER );

    for( n = nsent = 0; (0 == rc) && (nsent < (ssize_t)nlen);  ) {
        errno = 0;
        n = send( sockfd, buf, (int)nlen, 0 );

        if( (-1 == n) && (EINTR != errno) ) {
            mperror(g_flog, errno, "%s: send", __func__);
            rc = ERR_INTERNAL;
            break;
        }

        nsent += n;
    }

    if( 0 != rc ) {
        TRACE( (void)tmfprintf( g_flog, "Error generating status report\n" ) );
    }
    else {
        /* DEBUG only
        TRACE( (void)tmfprintf( g_flog, "Saved status buffer to file\n" ) );
        TRACE( (void)save_buffer(buf, nlen, "/tmp/status-udpxy.html") );
        */
    }

    free(buf);
    return rc;
}
Ejemplo n.º 7
0
/* determine type of stream saved in file
 */
upxfmt_t
get_fstream_type( int fd, FILE* log )
{
    ssize_t n = 0;
    off_t offset = 0, where = 0;
    upxfmt_t dtype = UPXDT_UNKNOWN;
    char* data = NULL;

    /* read in enough data to contain extended header
     * and beginning of payload segment */
    size_t len = TS_SEG_LEN + RTP_XTHDRLEN;

    assert( (fd > 0) && log );

    if( NULL == (data = malloc( len )) ) {
        mperror( log, errno, "%s: malloc", __func__ );
        return UPXDT_UNKNOWN;
    }

    do {
        /* check if it is a MPEG TS stream
         */
        n = read( fd, data, len );
        if( 0 != sizecheck( "Not enough space for stream data",
                    len, n, log, __func__ ) ) break;
        offset += n;

        dtype = get_mstream_type( data, len, log );
        if( UPXDT_UNKNOWN == dtype ) {
            TRACE( (void)tmfprintf( log, "%s: file type is not recognized\n",
                        __func__ ) );
            dtype = UPXDT_UNKNOWN;
            break;
        }
    } while(0);

    if( NULL != data ) free( data );

    if( n <= 0 ) {
        mperror( log, errno, "%s", __func__ );
        return UPXDT_UNKNOWN;
    }

    where = lseek( fd, (-1) * offset, SEEK_CUR );
    if( -1 == where ) {
        mperror( log, errno, "%s: lseek", __func__ );
        return UPXDT_UNKNOWN;
    }

    /*
    TRACE( (void)tmfprintf( log, "%s: stream type = [%d]=[%s]\n",
                __func__, (int)dtype, fmt2str(dtype) ) );
    */

    return dtype;
}
Ejemplo n.º 8
0
/* \fcnfh
   Open database and auxiliary file, set all FILE pointers.
*/
static int
db_open(char *dbfilenameo, 
	char *dbaux)
{
  dbfilename = strdup(dbfilenameo);

  //Open database
  if((fp = fopen(dbfilename,"r")) == NULL)
    mperror(MSGP_USER,
	    "Could not open file '%s' for reading\n"
	    , dbfilename);

  int maxlen=50;
  char line[maxlen], *lp;
  const char *id = "#TLI-ASCII";

  if(fgets(line, maxlen-1, fp) && 
     strncmp(line, id, strlen(id)) != 0)
    mperror(MSGP_SYSTEM,
	    "File '%s' does not have the proper "
	    "TLI-ASCII heading, but it was approved "
	    "by db find(?)\n"
	    , dbfilename);

  currline = 1;
  size_t pos = ftell(fp);
  char rc;
  settoolongerr(&linetoolong_text,dbfilename,&currline);


  //skip comments and blank lines
  while((rc=fgetupto(line,maxline,fp)) == '#' || 
	rc == '\n')
    currline++;
  if(!rc) earlyend(dbfilename, currline);

  //get number of database which needs to be one at this point. If
  //omitted number of databases, it is assumed to be 1
  if (line[0] == 'd'){
    ndb = strtol(line+1, &lp, 0);
    if (lp == line+1) 
      mperror(MSGP_USER,
	      "Invalid number of databases in TLI-ASCII '%s'\n"
	      , dbfilename);
  }
  else{
    currline = ndb = 1;
    fseek(fp, pos, SEEK_SET);
  }

  return LR_OK;
}
Ejemplo n.º 9
0
/* make sure the channel is valid: subscribe/close
 */
static int
verify_channel()
{
    struct in_addr mcast_inaddr;
    int sockfd = -1, rc = -1;
    char buf[16];
    ssize_t nrd = -1;
    struct timeval rtv;

    static const time_t MSOCK_TMOUT_SEC = 2;

    rc = subscribe( &sockfd, &mcast_inaddr );
    do {
        if( rc ) break;

        rtv.tv_sec = MSOCK_TMOUT_SEC;
        rtv.tv_usec = 0;
        rc = setsockopt( sockfd, SOL_SOCKET, SO_RCVTIMEO, &rtv, sizeof(rtv) );
        if( -1 == rc ) {
            mperror(g_flog, errno, "%s: setsockopt - SO_RCVTIMEO",
                __func__);
            rc = ERR_INTERNAL; break;
        }

        /* attempt to read from the socket to
         * make sure the channel is alive
         */
        nrd = read( sockfd, buf, sizeof(buf) );
        if( nrd <= 0 ) {
            rc = errno;
            mperror( g_flog, errno, "channel read" );
            if( EAGAIN == rc ) {
                (void) tmfprintf( g_flog,
                        "failed to read from [%s:%d]\n",
                        g_recopt.rec_channel, g_recopt.rec_port );
            }
            rc = ERR_INTERNAL; break;
        }

        TRACE( (void)tmfprintf( g_flog, "%s: read [%ld] bytes "
                    "from source channel\n", __func__, nrd ) );
    } while(0);

    if( sockfd >= 0 ) {
        close_mcast_listener( sockfd, &mcast_inaddr );
    }

    return rc;
}
Ejemplo n.º 10
0
static int
get_sockbuf_size( int sockfd, int option, size_t* const len,
                  const char* bufname )
{
    int rc = 0;
    size_t buflen = 0;
    socklen_t varsz = sizeof(buflen);

    assert( sockfd && len && bufname );

    rc = getsockopt( sockfd, SOL_SOCKET, option, &buflen, &varsz );
    if (0 != rc) {
        mperror( g_flog, errno, "%s: getsockopt (%s) [%d]", __func__,
                bufname, option);
        return -1;
    }
    else {
        TRACE( (void)tmfprintf( g_flog,
            "current %s buffer size is [%u] bytes for socket [%d]\n",
            bufname, buflen, sockfd ) );
        *len = buflen;
    }

    return rc;

}
Ejemplo n.º 11
0
/* write data to destination(s)
 */
ssize_t
write_data( const struct dstream_ctx* spc,
            const char* data,
            const ssize_t len,
            int fd )
{
    ssize_t n = 0, error = IO_ERR;
    int32_t n_count = -1;

    assert( spc && data && len );
    if( fd <= 0 ) return 0;

    if( spc->flags & F_SCATTERED ) {
        n_count = spc->pkt_count;
        n = writev( fd, spc->pkt, n_count );
        if( n <= 0 ) {
            if( EAGAIN == errno ) {
                (void)tmfprintf( g_flog, "Write on fd=[%d] timed out\n", fd);
                error = IO_BLK;
            }
            mperror( g_flog, errno, "%s: writev", __func__ );
            return error;
        }
    }
    else {
        n = write_buf( fd, data, len, g_flog );
        if( n < 0 )
            error = n;
    }

    return (n > 0) ? n : error;
}
Ejemplo n.º 12
0
Archivo: udpxy.c Proyecto: avble/udpxy
/* clear SIGCHLD flag and adjust context if needed
 */
static void
wait_children( struct server_ctx* ctx, int options )
{
    int status, n = 0;
    pid_t pid;

    assert( ctx );
    if (0 == g_childexit) {
        TRACE( (void)tmfputs ("No children exited since last check\n",
                g_flog) );
        return;
    }

    g_childexit = 0;

    TRACE( (void)tmfputs ("Waiting on exited children\n", g_flog) );
    while( 0 < (pid = waitpid( -1, &status, options )) ) {
        TRACE( (void)tmfprintf( g_flog, "Client [%d] has exited.\n", pid) );
        delete_client( ctx, pid );
        ++n;
    }

    if( (-1 == pid) && ( ECHILD != errno ) ) {
        mperror(g_flog, errno, "%s: waitpid", __func__);
    }

    if (n > 0) {
        TRACE( (void)tmfprintf (g_flog, "Cleaned up %d children, "
            "%ld still running\n", n, (long)(ctx->clmax - ctx->clfree)) );
    }

    return;
}
Ejemplo n.º 13
0
Archivo: udpxy.c Proyecto: avble/udpxy
/* send HTTP response to socket
 */
static int
send_http_response( int sockfd, int code, const char* reason)
{
    static char msg[ 3072 ];
    ssize_t nsent;
    a_socklen_t msglen;
    static const char CONTENT_TYPE[] = "Content-Type:application/octet-stream";

    assert( (sockfd > 0) && code && reason );

    msg[0] = '\0';

    if ((200 == code) && g_uopt.h200_ftr[0]) {
        msglen = snprintf( msg, sizeof(msg) - 1, "HTTP/1.1 %d %s\r\nServer: %s\r\n%s\r\n%s\r\n\r\n",
            code, reason, g_udpxy_finfo, CONTENT_TYPE, g_uopt.h200_ftr);
    }
    else {
        msglen = snprintf( msg, sizeof(msg) - 1, "HTTP/1.1 %d %s\r\nServer: %s\r\n%s\r\n\r\n",
                code, reason, g_udpxy_finfo, CONTENT_TYPE );
    }
    if( msglen <= 0 ) return ERR_INTERNAL;

    nsent = send( sockfd, msg, msglen, 0 );
    if( -1 == nsent ) {
        mperror(g_flog, errno, "%s - send", __func__);
        return ERR_INTERNAL;
    }

    TRACE( (void)tmfprintf( g_flog, "Sent HTTP response code=[%d], "
                "reason=[%s] to socket=[%d]\n%s\n",
                code, reason, sockfd, msg) );
    return 0;
}
Ejemplo n.º 14
0
Archivo: ctx.c Proyecto: 5UN5H1N3/udpxy
/* initialize server context data
 */
int
init_server_ctx( struct server_ctx* ctx,
                 const size_t max,
                 const char* laddr, uint16_t lport,
                 const char* mifc_addr )
{
    int flags = -1;

    assert( lport && mifc_addr && ctx && max );

    ctx->lsockfd = 0;
    (void) strncpy( ctx->listen_addr, (laddr ? laddr : IPv4_ALL),
                    IPADDR_STR_SIZE );
    ctx->listen_addr[ IPADDR_STR_SIZE - 1 ] = '\0';

    ctx->listen_port = lport;

    (void) strncpy( ctx->mcast_ifc_addr, mifc_addr, IPADDR_STR_SIZE );
    ctx->mcast_ifc_addr[ IPADDR_STR_SIZE - 1 ] = '\0';

    ctx->cl = calloc(max, sizeof(struct client_ctx));
    if( NULL == ctx->cl ) {
        mperror( g_flog, errno, "%s: client_t - calloc", __func__ );
        return ERR_INTERNAL;
    }

    (void) memset( ctx->cl, 0, max * sizeof(struct client_ctx) );
    ctx->clfree = ctx->clmax = max;

    (void) memset( &ctx->rq, 0, sizeof(ctx->rq) );

    if( 0 != pipe(ctx->cpipe) ) {
        mperror( g_flog, errno, "%s: pipe", __func__ );
        return ERR_INTERNAL;
    }

    /* make reading end of pipe non-blocking (we don't want to
     * block on pipe read on the server side)
     */
    if( -1 == (flags = fcntl( ctx->cpipe[0], F_GETFL )) ||
        -1 == fcntl( ctx->cpipe[0], F_SETFL, flags | O_NONBLOCK ) ) {
        mperror( g_flog, errno, "%s: fcntl", __func__ );
        return ERR_INTERNAL;
    }

    return 0;
}
Ejemplo n.º 15
0
/* \fcnfh
   This function is called if a line of 'file' was longer than 'max'
   characters
*/
void 
linetoolong(int max,     /* Maxiumum length of an accepted line */
            char *file,  /* File from which we were reading     */
            int line){   /* Line who was being read             */
  mperror(MSGP_USER|MSGP_ALLOWCONT,
          "Line %i of file '%s' has more than %i characters.\n", file, max);
  exit(EXIT_FAILURE);
}
Ejemplo n.º 16
0
int main(void){
  char *argv[] = {"/bin/lsls", NULL};

  if(execve("/bin/lsls", argv, NULL) == -1) {
    mperror("execve", errno);
    exit(EXIT_FAILURE);
  }
  exit(EXIT_SUCCESS);
}
Ejemplo n.º 17
0
/* \fcnfh
   It outputs error. Used when EOF is found before expected
*/
static void
earlyend(char *file, long lin)
{
  mperror(MSGP_USER|MSGP_ALLOWCONT,
	       "readlineinfo:: EOF unexpectedly found at line %i in\n"
	       "ascii-TLI linedb info file '%s'\n"
	       ,lin,file);
  lineread_free();
  exit(EXIT_FAILURE);
}
Ejemplo n.º 18
0
static int
db_open(char *dbname, 
	char *dbaux)
{
  if((fp = fopen(dbname,"r")) == NULL)
    mperror(MSGP_USER,
	    "Could not open file '%s' for reading\n"
	    , dbname);

  return LR_OK;
}
Ejemplo n.º 19
0
/* ---------------- mfopen  -----------------------------------
 * Wrapper around fopen. Last arg is a string, typically the
 * name of the calling function which will be printed out at the
 * start of error messages.
 */
FILE *
mfopen (const char *fname, const char *mode, const char *s)
{
    FILE *fp;
    if ((fp = fopen (fname, mode)) == NULL) {
        int e = errno;
        err_printf (s, "Open fail on %s\n", fname);
        errno = e;
        mperror (s);
    }
    return fp;
}
Ejemplo n.º 20
0
static int
xfwrt (const void *data, size_t size, size_t nmem, FILE *fp,
               const char *caller, const char *fname)
{
    size_t r = fwrite(data,  size, nmem, fp) ;
    if (r != nmem) {
        mperror (caller);
        err_printf (caller, "Trying to write to %s\n", fname);
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
Ejemplo n.º 21
0
/* make current process run as a daemon
 */
int
daemonize(int options, FILE* log)
{
    pid_t pid;
    int rc = 0, fh = -1;

    assert( log );

    if( (pid = fork()) < 0 ) {
        mperror( log, errno,
                "%s: fork", __func__);
        return -1;
    }
    else if( 0 != pid ) {
        exit(0);
    }

    do {
        if( -1 == (rc = setsid()) ) {
            mperror( log, errno,
                    "%s: setsid", __func__);
            break;
        }

        if( -1 == (rc = chdir("/")) ) {
            mperror( log, errno, "%s: chdir", __func__ );
            break;
        }

        (void) umask(0);

        if( !(options & DZ_STDIO_OPEN) ) {
            for( fh = 0; fh < 3; ++fh )
                if( -1 == (rc = close(fh)) ) {
                    mperror( log, errno, "%s: close", __func__);
                    break;
                }
        }

        if( SIG_ERR == signal(SIGHUP, SIG_IGN) ) {
            mperror( log, errno, "%s: signal", __func__ );
            rc = 2;
            break;
        }

    } while(0);

    if( 0 != rc ) return rc;

    /* child exits to avoid session leader's re-acquiring
     * control terminal */
    if( (pid = fork()) < 0 ) {
        mperror( log, errno, "%s: fork", __func__);
        return -1;
    }
    else if( 0 != pid )
        exit(0);

    return 0;
}
Ejemplo n.º 22
0
/* register received packet into registry (for scattered output)
 */
static int
register_packet( struct dstream_ctx* spc, char* buf, size_t len )
{
    struct iovec* new_pkt = NULL;
    static const int DO_VERIFY = 1;

    void* new_buf = buf;
    size_t new_len = len;

    assert( spc->max_pkt > 0 );

    /* enlarge packet registry if needed */
    if( spc->pkt_count >= spc->max_pkt ) {
        spc->max_pkt <<= 1;
        spc->pkt = realloc( spc->pkt, spc->max_pkt * sizeof(spc->pkt[0]) );
        if( NULL == spc->pkt ) {
            mperror( g_flog, errno, "%s: realloc", __func__ );
            return -1;
        }

        TRACE( (void)tmfprintf( g_flog, "RTP packet registry "
                "expanded to [%lu] records\n", (u_long)spc->max_pkt ) );
    }

    /* put packet info into registry */

    new_pkt = &(spc->pkt[ spc->pkt_count ]);

    /*
    TRACE( (void)tmfprintf( stderr, "IN: packet [%lu]: buf=[%p], len=[%lu]\n",
                (u_long)spc->pkt_count, (void*)buf, (u_long)len ) );
    */

    if( 0 != RTP_process( &new_buf, &new_len, DO_VERIFY, g_flog ) ) {
        TRACE( (void)tmfputs("register packet: dropping\n", g_flog) );
        spc->flags |= F_DROP_PACKET;

        return 0;
    }

    new_pkt->iov_base = new_buf;
    new_pkt->iov_len = new_len;

    /*
    TRACE( (void)tmfprintf( stderr, "OUT: packet [%lu]: buf=[%p], len=[%lu]\n",
                (u_long)spc->pkt_count, new_pkt->iov_base,
                (u_long)new_pkt->iov_len ) );
    */

    spc->pkt_count++;
    return 0;
}
Ejemplo n.º 23
0
Archivo: ctx.c Proyecto: 5UN5H1N3/udpxy
/* read client statistics data and update the context
 */
int
tpstat_read( struct server_ctx* ctx )
{
    int cindex = -1;
    int readfd = -1;
    ssize_t nread = 0;
    struct tput_stat ts;
    struct client_ctx* client = NULL;

    assert( ctx );

    readfd = ctx->cpipe[0];
    assert( readfd > 0 );

    (void)memset( &ts, 0, sizeof(ts) );

    nread = read( readfd, &ts, sizeof(ts) );
    if( nread <= 0 ) {
        if( (EINTR != errno) && (EAGAIN != errno) ) {
            mperror( g_flog, errno, "%s: read", __func__ );
            return ERR_INTERNAL;
        }
        /* if it's an interrupt or no data available - ignore */
        TRACE( (void)tmfprintf( g_flog, "%s - read error [%s] - ingored\n",
                        __func__, strerror(errno)) );
        return 0;
    }
    if( sizeof(ts) != (size_t)nread ) {
        (void)tmfprintf( g_flog, "%s - read [%d] bytes from pipe, expected [%u]\n",
                __func__, nread, (int)sizeof(ts) );
        return ERR_INTERNAL;
    }

    TRACE( (void)tmfprintf( g_flog,
            "Received TSTAT={ sender=[%ld], bytes=[%f], seconds=[%f] }\n",
            (long)ts.sender_id, ts.nbytes, ts.nsec) );

    cindex = find_client( ctx, (pid_t)ts.sender_id );
    if( -1 == cindex ) {
        (void)tmfprintf( g_flog, "%s - cannot find client [%ld]\n",
                __func__, (long)ts.sender_id );
        /* ignore invalid client id's */
        return 0;
    }

    client = &(ctx->cl[ cindex ]);
    client->tstat = ts;

    TRACE( (void)tmfprintf( g_flog, "Updated context for pid=[%d]; "
                "[%.1f] Kb/sec\n", client->pid, (ts.nbytes / 1024) / ts.nsec  ) );
    return 0;
}
Ejemplo n.º 24
0
/* \fcnfh
   print out an error, it is called by readdatarng if one of the field
   with transition info is invalid

   @returns -5 always
*/
static int
invalidfield(char *line,	/* Contents of the line */
	     char *file,	/* File name */
	     int nmb,		/* File number */
	     int fld,		/* field with the error */
	     char *fldn)	/* Name of the field */
{
  mperror(MSGP_USER|MSGP_ALLOWCONT,
	       "Line %i of file '%s': Field %i (%s) has\n"
	       " not a valid value:\n%s\n"
	       ,nmb,file,fld,fldn,line);
  return -5;
}
Ejemplo n.º 25
0
/* send HTTP response to socket
 */
static int
send_http_response( int sockfd, int code, const char* reason)
{
    static char msg[ 3072 ];
    ssize_t nsent;
    a_socklen_t msglen;
    int err = 0;

    assert( (sockfd > 0) && code && reason );

    msg[0] = '\0';

    if ((200 == code) && g_uopt.h200_ftr[0]) {
        msglen = snprintf( msg, sizeof(msg) - 1, "HTTP/1.1 %d %s\r\nServer: %s\r\n%s\r\n%s\r\n\r\n",
            code, reason, g_app_info, g_uopt.cnt_type, g_uopt.h200_ftr);
    }
    else {
        msglen = snprintf( msg, sizeof(msg) - 1, "HTTP/1.1 %d %s\r\nServer: %s\r\n%s\r\n\r\n",
                code, reason, g_app_info, g_uopt.cnt_type );
    }
    if( msglen <= 0 ) return ERR_INTERNAL;

    nsent = send( sockfd, msg, msglen, 0 );
    if( -1 == nsent ) {
        err = errno;
        if( !no_fault(err) )
            mperror(g_flog, err, "%s - send", __func__);
        else {
            TRACE( mperror(g_flog, err, "%s - send", __func__) );
        }
        return ERR_INTERNAL;
    }

    TRACE( (void)tmfprintf( g_flog, "Sent HTTP response code=[%d], "
                "reason=[%s] to socket=[%d]\n%s\n",
                code, reason, sockfd, msg) );
    return 0;
}
Ejemplo n.º 26
0
Archivo: ctx.c Proyecto: 5UN5H1N3/udpxy
/* populate connection's source info in client context
 */
static int
get_src_info( struct client_ctx* cl, int sockfd )
{
    struct stat st;
    struct sockaddr_in addr;
    a_socklen_t len = 0;
    int rc = 0;

    assert( cl );
    if( -1 == (rc = fstat( sockfd, &st )) ) {
        mperror( g_flog, errno, "%s: fstat", __func__ );
        return ERR_INTERNAL;
    }

    if( S_ISREG( st.st_mode ) ) {
        (void) strncpy( cl->src_addr, "File", sizeof(cl->src_addr) );
        cl->src_addr[ sizeof(cl->src_addr) - 1 ] = '\0';
        cl->src_port = 0;
    }
    else if( S_ISSOCK( st.st_mode ) ) {
        len = sizeof(addr);
        rc = getpeername( sockfd, (struct sockaddr*)&addr, &len );
        if( 0 == rc ) {
            (void)strncpy( cl->src_addr, inet_ntoa(addr.sin_addr),
                    sizeof(cl->src_addr) - 1 );
            cl->src_addr[ sizeof(cl->src_addr) - 1 ] = '\0';

            cl->src_port = ntohs(addr.sin_port);
        }
        else {
            mperror( g_flog, errno, "%s: getpeername", __func__ );
            return ERR_INTERNAL;
        }
    } /* S_ISSOCK */

    return rc;
}
Ejemplo n.º 27
0
/* read text file into a buffer
 *
 */
ssize_t
txtf_read (const char* fpath, char* dst, size_t maxlen, FILE* log)
{
    int rc = 0, fd = -1;
    ssize_t n = 0;
    ssize_t left = maxlen - 1;
    char *p = dst;

    assert (fpath && dst && maxlen);
    fd = open (fpath, O_RDONLY, 0);
    if (-1 == fd) {
        mperror (log, errno, "%s open %s", __func__, fpath);
        return -1;
    }

    while (left > 0) {
        n = read (fd, p, maxlen - 1);
        if (!n) break;
        if (n < 0) {
            n = 0; rc = errno;
            if (EINTR != rc) {
                mperror (log, errno, "%s read %s", __func__, fpath);
                break;
            }
            rc = 0;
        }
        left -= (size_t)n;
        p += n;
    }
    if (!rc) *p = '\0';

    if (-1 == close (fd)) {
        mperror (log, errno, "%s close %s", __func__, fpath);
    }
    return (rc ? -1 : ((ssize_t)maxlen - left - 1));
}
Ejemplo n.º 28
0
/* write buffer to designated socket/file
 */
ssize_t
write_buf( int fd, const char* data, const ssize_t len, FILE* log )
{
    ssize_t n = 0, nwr = 0, error = IO_ERR;
    int err = 0;

    for( n = 0; errno = 0, n < len ; ) {
        nwr = write( fd, &(data[n]), len - n );
        if( nwr <= 0 ) {
            err = errno;
            if( EINTR == err ) {
                TRACE( (void)tmfprintf( log,
                            "%s interrupted\n", __func__ ) );
                continue;
            }
            else {
                if( would_block(err) )
                    error = IO_BLK;

                break;
            }
        }

        n += nwr;

        if( nwr != len ) {
            if( NULL != log ) {
                TRACE( (void)tmfprintf( log,
                        "Fragment written %s[%ld:%ld]/[%ld] bytes\n",
                        (len > n ? "P" : "F"), (long)nwr, (long)n, (long)len ) );
            }
        }

    }

    if( nwr <= 0 ) {
        if( log ) {
            if (IO_BLK == error)
                (void)tmfprintf( log, "%s: socket time-out on write", __func__);
            else if( !no_fault(err) || g_uopt.is_verbose )
                mperror( log, errno, "%s: write", __func__ );
        }

        return error;
    }

    return n;
}
Ejemplo n.º 29
0
/* ---------------- xfrd  -------------------------------------
 * Noisy wrapper around fread. Make it more convenient to
 * print out the sys error message and name of the file.
 * Return EXIT_SUCCESS/FAILURE.
 */
static int
xfrd (void *data, size_t size, size_t nmem, FILE *fp,
      const char *caller, const char *fname)
{
    size_t r = fread (data, size, nmem, fp);
    if (r != nmem) {
        if (errno)
            mperror (caller);
        err_printf (caller, "Trying to read from %s\n", fname);
        err_printf (caller, "Wanted %u elements, got %u\n",
                    (unsigned) nmem, (unsigned) r);
                    
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
Ejemplo n.º 30
0
Archivo: udpxy.c Proyecto: avble/udpxy
/* read HTTP request from sockfd, parse it into command
 * and its parameters (for instance, command='udp' and
 * parameters being '192.168.0.1:5002')
 */
static int
read_command( int sockfd, char* cmd, size_t clen,
              char* param, size_t plen )
{
#define DBUF_SZ 2048  /* max size for raw data with HTTP request */
#define RBUF_SZ 512   /* max size for url-derived request */
    char httpbuf[ DBUF_SZ ] = "\0", request[ RBUF_SZ ] = "\0";
    ssize_t hlen;
    size_t  rlen;
    int rc = 0;

    assert( (sockfd > 0) && cmd && clen && param && plen );
    cmd[0] = '\0';  /* forget previous command */

    TRACE( (void)tmfprintf( g_flog,  "Reading command from socket [%d]\n",
                            sockfd ) );
    hlen = recv( sockfd, httpbuf, sizeof(httpbuf), 0 );
    if( 0>hlen ) {
        rc = errno;
        mperror(g_flog, rc, "%s - recv (%d)", __func__, rc);
        return rc;
    }
    if (0 == hlen) {
        (void) tmfprintf (g_flog, "%s: client closed socket [%d]\n",
            __func__, sockfd);
        return 1;
    }

    /* DEBUG - re-enable if needed */
    TRACE( (void)tmfprintf( g_flog, "HTTP buffer [%ld bytes] received\n%s", (long)hlen, httpbuf ) );
    /* TRACE( (void) save_buffer( httpbuf, hlen, "/tmp/httpbuf.dat" ) ); */

    rlen = sizeof(request);
    rc = get_request( httpbuf, (size_t)hlen, request, &rlen );
    if (rc) return rc;

    TRACE( (void)tmfprintf( g_flog, "Request=[%s], length=[%lu]\n",
                request, (u_long)rlen ) );

    rc = parse_param( request, rlen, cmd, clen, param, plen );
    if( 0 == rc ) {
        TRACE( (void)tmfprintf( g_flog, "Command [%s] with params [%s]"
                    " read from socket=[%d]\n", cmd, param, sockfd) );
    }

    return rc;
}