<commit_before>/* * 
 *  $Id$
 *  
 *  This file is part of Fenice
 *
 *  Fenice -- Open Media Server
 *
 *  Copyright (C) 2004 by
 *      
 *    - <NAME>    <<EMAIL>>
 *    - <NAME>    <<EMAIL>>
 *    - <NAME>        <<EMAIL>>
 *    - <NAME>    <<EMAIL>>
 *    - <NAME>     <<EMAIL>>
 *    - <NAME>
 *    - <NAME>
 *    - <NAME>
 *    - <NAME>    <<EMAIL>>
 * 
 *  Fenice is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  Fenice is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Fenice; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *  
 * */

#include <glib.h>

#include <fenice/rtsp.h>
#include <fenice/prefs.h>
#include <fenice/multicast.h>
#include <fenice/fnc_log.h>

#include <RTSP_utils.h>

RTSP_Error split_resource_path(ConnectionInfo * cinfo, char * trackname, size_t trackname_max_len);
RTSP_Error parse_transport_header(RTSP_buffer * rtsp, RTP_transport * transport, unsigned char * is_multicast_dad);

/*
     ****************************************************************
     *            SETUP METHOD HANDLING
     ****************************************************************
*/
int RTSP_setup(RTSP_buffer * rtsp, RTSP_session ** new_session)
{
    ConnectionInfo cinfo;
    char url[255];
    long int session_id = 0;
    char trackname[255];
    RTP_transport transport;

    Selector *track_sel;
    Track *req_track;

    //mediathread pointers
    RTP_session *rtp_s;
    RTSP_session *rtsp_s;
    unsigned char is_multicast_dad = 1;    //unicast and the first multicast

    struct timeval now_tmp;
    unsigned int start_seq, start_rtptime;

    RTSP_Error error;

    // init
    memset(&transport, 0, sizeof(transport));

    // Parse the input message

    if ( (error = extract_url(rtsp, url)).got_error ) // Extract the URL
	    goto error_management;
    else if ( (error = validate_url(url, &cinfo)).got_error ) // Validate URL
    	goto error_management;
    else if ( (error = check_forbidden_path(&cinfo)).got_error ) // Check for Forbidden Paths
    	goto error_management;
    else if ( (error = split_resource_path(&cinfo, trackname, sizeof(trackname))).got_error ) //Split resource!trackname
        goto error_management;
    else if ( (error = get_cseq(rtsp)).got_error ) // Get the CSeq 
        goto error_management;
    else if ( (error = parse_transport_header(rtsp, &transport, &is_multicast_dad)).got_error )
        goto error_management;

    // printf("rtp transport: %d\n", transport->type);
    if (!transport.rtp_sock) {
        // fnc_log(FNC_LOG_ERR,"Unsupported Transport\n");
        set_RTSP_Error(&error, 461, "Unsupported Transport");
        goto error_management;
    }
    // If there's a Session header we have an aggregate control
    if ( (error = get_session_id(rtsp, &session_id)).got_error )
        goto error_management;
    else {
        // Generate a random Session number
        gettimeofday(&now_tmp, 0);
        srand((now_tmp.tv_sec * 1000) + (now_tmp.tv_usec / 1000));
#ifdef WIN32
        session_id = rand();
#else
        session_id = 1 + (int) (10.0 * rand() / (100000 + 1.0));
#endif
        if (session_id == 0) {
            session_id++;
        }
#if 0 // To support multiple session per socket...
        // XXX Paranoia make sure we have a connection limit set elsewhere...
        while (rtsp_session_from_id(rtsp, session_id))
#ifdef WIN32
            session_id = rand();
#else
            session_id = 1 + (int) (10.0 * rand() / (100000 + 1.0));
#endif

#endif
    }

    // Add an RTSP session if necessary
    // XXX Append a new session if one isn't present already!
#if 1
    if (!rtsp->session_list) {
        rtsp->session_list = calloc(1, sizeof(RTSP_session));
    }
    rtsp_s = rtsp->session_list;
#else // To support multiple session per socket...
    if (!rtsp->session_list) {
        rtsp->session_list = calloc(1, sizeof(RTSP_session));
        rtsp_s = rtsp->session_list;
    } else {
        RTSP_session *rtsp_s_prec;
        for (rtsp_s = rtsp->session_list; rtsp_s != NULL;
             rtsp_s = rtsp_s->next) {
            rtsp_s_prec = rtsp_s;
        }
        rtsp_s_prec->next = calloc(1, sizeof(RTP_session));
        rtsp_s = rtsp_s_prec->next;
    }
#endif

    // it should parse the request giving us object!trackname
    if (!rtsp_s->resource) {
        if ((rtsp_s->resource = mt_resource_open(prefs_get_serv_root(),
                                                cinfo.object))) {
            send_reply(404, 0, rtsp);//TODO: Not found or Internal server error?
            fnc_log(FNC_LOG_DEBUG, "Resource for %s not found\n", cinfo.object);
            return ERR_NOERROR;
        }
    }

    if ((track_sel = r_open_tracks(rtsp_s->resource, trackname, NULL))) {
        send_reply(404, 0, rtsp);    // Not found
        fnc_log(FNC_LOG_DEBUG, "Track %s not present in resource %s\n",
                trackname, cinfo.object);
        return ERR_NOERROR;
    }

    if ((req_track = r_selected_track(track_sel))) {
        send_reply(500, 0, rtsp);    // Internal server error
        return ERR_NOERROR;
    }

// Setup the RTP session
    if (rtsp->session_list->rtp_session == NULL) {
        rtsp->session_list->rtp_session = calloc(1, sizeof(RTP_session));
        rtp_s = rtsp->session_list->rtp_session;
    } else {
        rtp_s = rtsp_s->rtp_session;
        while (rtp_s->next !=  NULL) {
            rtp_s = rtp_s->next;
        };
        rtp_s->next = calloc(1, sizeof(RTP_session));
        rtp_s = rtp_s->next;
    }

#ifdef WIN32
    start_seq = rand();
    start_rtptime = rand();
#else
    start_seq = 1 + (unsigned int) (rand() % (0xFFFF));
    start_rtptime = 1 + (unsigned int) (rand() % (0xFFFFFFFF));
#endif
    if (start_seq == 0) {
        start_seq++;<commit_msg>5+5l to amol for ignoring !, for me for being that slow<commit_after>/* * 
 *  $Id$
 *  
 *  This file is part of Fenice
 *
 *  Fenice -- Open Media Server
 *
 *  Copyright (C) 2004 by
 *      
 *    - <NAME>    <<EMAIL>>
 *    - <NAME>    <<EMAIL>>
 *    - <NAME>        <<EMAIL>>
 *    - <NAME>    <<EMAIL>>
 *    - <NAME>     <<EMAIL>>
 *    - <NAME>
 *    - <NAME>
 *    - <NAME>
 *    - <NAME>    <<EMAIL>>
 * 
 *  Fenice is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  Fenice is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Fenice; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *  
 * */

#include <glib.h>

#include <fenice/rtsp.h>
#include <fenice/prefs.h>
#include <fenice/multicast.h>
#include <fenice/fnc_log.h>

#include <RTSP_utils.h>

RTSP_Error split_resource_path(ConnectionInfo * cinfo, char * trackname, size_t trackname_max_len);
RTSP_Error parse_transport_header(RTSP_buffer * rtsp, RTP_transport * transport, unsigned char * is_multicast_dad);

/*
     ****************************************************************
     *            SETUP METHOD HANDLING
     ****************************************************************
*/
int RTSP_setup(RTSP_buffer * rtsp, RTSP_session ** new_session)
{
    ConnectionInfo cinfo;
    char url[255];
    long int session_id = 0;
    char trackname[255];
    RTP_transport transport;

    Selector *track_sel;
    Track *req_track;

    //mediathread pointers
    RTP_session *rtp_s;
    RTSP_session *rtsp_s;
    unsigned char is_multicast_dad = 1;    //unicast and the first multicast

    struct timeval now_tmp;
    unsigned int start_seq, start_rtptime;

    RTSP_Error error;

    // init
    memset(&transport, 0, sizeof(transport));

    // Parse the input message

    if ( (error = extract_url(rtsp, url)).got_error ) // Extract the URL
	    goto error_management;
    else if ( (error = validate_url(url, &cinfo)).got_error ) // Validate URL
    	goto error_management;
    else if ( (error = check_forbidden_path(&cinfo)).got_error ) // Check for Forbidden Paths
    	goto error_management;
    else if ( (error = split_resource_path(&cinfo, trackname, sizeof(trackname))).got_error ) //Split resource!trackname
        goto error_management;
    else if ( (error = get_cseq(rtsp)).got_error ) // Get the CSeq 
        goto error_management;
    else if ( (error = parse_transport_header(rtsp, &transport, &is_multicast_dad)).got_error )
        goto error_management;

    // printf("rtp transport: %d\n", transport->type);
    if (!transport.rtp_sock) {
        // fnc_log(FNC_LOG_ERR,"Unsupported Transport\n");
        set_RTSP_Error(&error, 461, "Unsupported Transport");
        goto error_management;
    }
    // If there's a Session header we have an aggregate control
    if ( (error = get_session_id(rtsp, &session_id)).got_error )
        goto error_management;
    else {
        // Generate a random Session number
        gettimeofday(&now_tmp, 0);
        srand((now_tmp.tv_sec * 1000) + (now_tmp.tv_usec / 1000));
#ifdef WIN32
        session_id = rand();
#else
        session_id = 1 + (int) (10.0 * rand() / (100000 + 1.0));
#endif
        if (session_id == 0) {
            session_id++;
        }
#if 0 // To support multiple session per socket...
        // XXX Paranoia make sure we have a connection limit set elsewhere...
        while (rtsp_session_from_id(rtsp, session_id))
#ifdef WIN32
            session_id = rand();
#else
            session_id = 1 + (int) (10.0 * rand() / (100000 + 1.0));
#endif

#endif
    }

    // Add an RTSP session if necessary
    // XXX Append a new session if one isn't present already!
#if 1
    if (!rtsp->session_list) {
        rtsp->session_list = calloc(1, sizeof(RTSP_session));
    }
    rtsp_s = rtsp->session_list;
#else // To support multiple session per socket...
    if (!rtsp->session_list) {
        rtsp->session_list = calloc(1, sizeof(RTSP_session));
        rtsp_s = rtsp->session_list;
    } else {
        RTSP_session *rtsp_s_prec;
        for (rtsp_s = rtsp->session_list; rtsp_s != NULL;
             rtsp_s = rtsp_s->next) {
            rtsp_s_prec = rtsp_s;
        }
        rtsp_s_prec->next = calloc(1, sizeof(RTP_session));
        rtsp_s = rtsp_s_prec->next;
    }
#endif

    // it should parse the request giving us object!trackname
    if (!rtsp_s->resource) {
        if (!(rtsp_s->resource = mt_resource_open(prefs_get_serv_root(),
                                                cinfo.object))) {
            send_reply(404, 0, rtsp);//TODO: Not found or Internal server error?
            fnc_log(FNC_LOG_DEBUG, "Resource for %s not found\n", cinfo.object);
            return ERR_NOERROR;
        }
    }

    if (!(track_sel = r_open_tracks(rtsp_s->resource, trackname, NULL))) {
        send_reply(404, 0, rtsp);    // Not found
        fnc_log(FNC_LOG_DEBUG, "Track %s not present in resource %s\n",
                trackname, cinfo.object);
        return ERR_NOERROR;
    }

    if (!(req_track = r_selected_track(track_sel))) {
        send_reply(500, 0, rtsp);    // Internal server error
        return ERR_NOERROR;
    }

// Setup the RTP session
    if (rtsp->session_list->rtp_session == NULL) {
        rtsp->session_list->rtp_session = calloc(1, sizeof(RTP_session));
        rtp_s = rtsp->session_list->rtp_session;
    } else {
        rtp_s = rtsp_s->rtp_session;
        while (rtp_s->next !=  NULL) {
            rtp_s = rtp_s->next;
        };
        rtp_s->next = calloc(1, sizeof(RTP_session));
        rtp_s = rtp_s->next;
    }

#ifdef WIN32
    start_seq = rand();
    start_rtptime = rand();
#else
    start_seq = 1 + (unsigned int) (rand() % (0xFFFF));
    start_rtptime = 1 + (unsigned int) (rand() % (0xFFFFFFFF));
#endif
    if (start_seq == 0) {
        start_seq++;
{'fraction_non_alphanumeric': 0.13552851348126937, 'fraction_numerical': 0.01527081842042472, 'mean_word_length': 2.6090700344431688, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 107, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4466279', 'n_tokens_mistral': 4275, 'n_tokens_neox': 4084, 'n_words': 1099}