コード例 #1
0
/*
* init_server()
*   Starts up listening socket
*/
int init_server()
{
	int on = 1;
	
	// Communications sockets
	
	if (ENABLE_VB) {
		// tcp:
		gs_coms_skt = tcpsock();  
		if (setsockopt(gs_coms_skt, SOL_SOCKET,SO_REUSEADDR, (char*)&on, sizeof(on)) < 0) {
			printf("Error Reusing Socket\n");
		}	
		sockbind(gs_coms_skt, gs_port_coms);
		socklisten(gs_coms_skt);
		printf("TCP Listening on port %d\n.",gs_port_coms);
		sock_set_nonblocking(gs_coms_skt);  // was blocking
	}
	
	// udp: 
	if (firsttime) {
		gs_udpcoms_skt = udpsock();
		sock_set_nonblocking(gs_udpcoms_skt);      
		sockbind(gs_udpcoms_skt, UDP_PORT);
		printf("UDP Listening on port %d\n.", UDP_PORT);
	}
}
コード例 #2
0
ファイル: rtpproxy_relay.c プロジェクト: OPSF/uClinux
/*
 * start an rtp stream on the proxy
 *
 * RETURNS
 *	STS_SUCCESS on success
 *	STS_FAILURE on error
 */
int rtp_relay_start_fwd (osip_call_id_t *callid, char *client_id,
                         int rtp_direction,
                         int media_stream_no, struct in_addr local_ipaddr,
                         int *local_port, struct in_addr remote_ipaddr,
                         int remote_port) {
   static int prev_used_port = 0;
   int num_ports;
   int i2, i, j;
   int sock, port;
   int freeidx;
   int sts=STS_SUCCESS;
   int tos;
   osip_call_id_t cid;
   

   if (callid == NULL) {
      ERROR("rtp_relay_start_fwd: callid is NULL!");
      return STS_FAILURE;
   }

   if (client_id == NULL) {
      ERROR("rtp_relay_start_fwd: did not get a client ID!");
      return STS_FAILURE;
   }

   /*
    * life insurance: check size of received call_id strings
    * I don't know what the maximum allowed size within SIP is,
    * so if this test fails maybe it's just necessary to increase
    * the constants CALLIDNUM_SIZE and/or CALLIDHOST_SIZE.
    */
   if (callid->number && strlen(callid->number) > CALLIDNUM_SIZE) {
      ERROR("rtp_relay_start_fwd: received callid number "
            "has too many characters (%i, max=%i)",
            strlen(callid->number),CALLIDNUM_SIZE);
      return STS_FAILURE;
   }
   if (callid->host && strlen(callid->host) > CALLIDHOST_SIZE) {
      ERROR("rtp_relay_start_fwd: received callid host "
            "has too many characters (%i, max=%i)",
            strlen(callid->host),CALLIDHOST_SIZE);
      return STS_FAILURE;
   }
   if (client_id && strlen(client_id) > CLIENT_ID_SIZE) {
      ERROR("rtp_relay_start_fwd: client ID has too many characters "
            "(%i, max=%i) (maybe you need to increase CLIENT_ID_SIZE",
            strlen(client_id),CLIENT_ID_SIZE);
      return STS_FAILURE;
   }

   DEBUGC(DBCLASS_RTP,"rtp_relay_start_fwd: starting RTP proxy "
          "stream for: %s@%s[%s] (%s) #=%i",
          callid->number, callid->host, client_id,
          ((rtp_direction == DIR_INCOMING) ? "incoming RTP" : "outgoing RTP"),
          media_stream_no);

   /* lock mutex */
   #define return is_forbidden_in_this_code_section
   pthread_mutex_lock(&rtp_proxytable_mutex);
   /*
    * !! We now have a locked MUTEX! It is forbidden to return() from
    * !! here up to the end of this funtion where the MUTEX is
    * !! unlocked again.
    * !! Per design, a mutex is locked (for one purpose) at *exactly one*
    * !! place in the code and unlocked also at *exactly one* place.
    * !! this minimizes the risk of deadlocks.
    */

   /*
    * figure out, if this is an request to start an RTP proxy stream
    * that is already existing (identified by SIP Call-ID, direction,
    * media_stream_no and some other client unique thing).
    * This can be due to UDP repetitions of the INVITE request...
    */
   for (i=0; i<RTPPROXY_SIZE; i++) {
      cid.number = rtp_proxytable[i].callid_number;
      cid.host   = rtp_proxytable[i].callid_host;
      if (rtp_proxytable[i].rtp_rx_sock &&
         (compare_callid(callid, &cid) == STS_SUCCESS) &&
         (rtp_proxytable[i].direction == rtp_direction) &&
         (rtp_proxytable[i].media_stream_no == media_stream_no) &&
         (strcmp(rtp_proxytable[i].client_id, client_id) == 0)) {
         /*
          * The RTP port number reported by the UA MAY change
          * for a given media stream
          * (seen with KPhone during HOLD/unHOLD)
          * Also the destination IP may change during a re-Invite
          * (seen with Sipphone.com, re-Invites when using
          * the SIP - POTS gateway [SIP Minutes] 
          */
         /* Port number */
         if (rtp_proxytable[i].remote_port != remote_port) {
            DEBUGC(DBCLASS_RTP,"RTP port number changed %i -> %i",
                   rtp_proxytable[i].remote_port, remote_port);
            rtp_proxytable[i].remote_port = remote_port;
         }
         /* IP address */
         if (memcmp(&rtp_proxytable[i].remote_ipaddr, &remote_ipaddr,
                    sizeof(remote_ipaddr))) {
            DEBUGC(DBCLASS_RTP,"RTP IP address changed to %s",
                   utils_inet_ntoa(remote_ipaddr));
            memcpy (&rtp_proxytable[i].remote_ipaddr, &remote_ipaddr,
                     sizeof(remote_ipaddr));
         }
         /* return the already known local port number */
         DEBUGC(DBCLASS_RTP,"RTP stream already active (remaddr=%s, "
                "remport=%i, lclport=%i, id=%s, #=%i)",
                utils_inet_ntoa(remote_ipaddr),
                rtp_proxytable[i].remote_port,
                rtp_proxytable[i].local_port,
                rtp_proxytable[i].callid_number,
                rtp_proxytable[i].media_stream_no);
	 *local_port=rtp_proxytable[i].local_port;
	 sts = STS_SUCCESS;
	 goto unlock_and_exit;
      }
   }


   /*
    * find first free slot in rtp_proxytable
    */
   freeidx=-1;
   for (j=0; j<RTPPROXY_SIZE; j++) {
      if (rtp_proxytable[j].rtp_rx_sock==0) {
         freeidx=j;
	 break;
      }
   }

   /* rtp_proxytable port pool full? */
   if (freeidx == -1) {
      ERROR("rtp_relay_start_fwd: rtp_proxytable is full!");
      sts = STS_FAILURE;
      goto unlock_and_exit;
   }

   /* TODO: randomize the port allocation - start at a random offset to
         search in the allowed port range (so some modulo stuff w/
	 random start offset 
	 - for i=x to (p1-p0)+x; p=p0+mod(x,p1-p0) */

   /* find a local port number to use and bind to it */
   sock=0;
   port=0;

   if ((prev_used_port < configuration.rtp_port_low) ||
       (prev_used_port > configuration.rtp_port_high)) {
      prev_used_port = configuration.rtp_port_high;
   }

   num_ports = configuration.rtp_port_high - configuration.rtp_port_low + 1;
   for (i2 = (prev_used_port - configuration.rtp_port_low + 1);
        i2 < (num_ports + prev_used_port - configuration.rtp_port_low + 1);
        i2 += 2) {
      i = (i2%num_ports) + configuration.rtp_port_low;
      for (j=0; j<RTPPROXY_SIZE; j++) {
         /* check if port already in use */
         if ((memcmp(&rtp_proxytable[j].local_ipaddr,
	             &local_ipaddr, sizeof(struct in_addr))== 0) &&
	     (rtp_proxytable[j].local_port == i) ) break;
      }

      /* port is available, try to allocate */
      if (j == RTPPROXY_SIZE) {
         port=i;
         sock=sockbind(local_ipaddr, port, 0);
         /* if success break, else try further on */
         if (sock) break;
      }
   } /* for i */
   prev_used_port = port;

   DEBUGC(DBCLASS_RTP,"rtp_relay_start_fwd: addr=%s, port=%i, sock=%i "
          "freeidx=%i", utils_inet_ntoa(local_ipaddr), port, sock, freeidx);

   /* found an unused port? No -> RTP port pool fully allocated */
   if ((port == 0) || (sock == 0)) {
      ERROR("rtp_relay_start_fwd: no RTP port available or bind() failed");
      sts = STS_FAILURE;
      goto unlock_and_exit;
   }

   /* set DSCP value, need to be ROOT */
   if (configuration.rtp_dscp) {
      int uid,euid;
      uid=getuid();
      euid=geteuid();
      DEBUGC(DBCLASS_RTP,"uid=%i, euid=%i", uid, euid);
      if (uid != euid) seteuid(0);
      if (geteuid()==0) {
         /* now I'm root */
         if (!(configuration.rtp_dscp & ~0x3f)) {
            tos = (configuration.rtp_dscp << 2) & 0xff;
            if(setsockopt(sock, SOL_IP, IP_TOS, &tos, sizeof(tos))) {
               ERROR("rtp_relay_start_fwd: setsockopt() failed while "
                     "setting DSCP value: ", strerror(errno));
            }
         } else {
            ERROR("rtp_relay_start_fwd: Invalid DSCP value %d",
                  configuration.rtp_dscp);
            configuration.rtp_dscp = 0; /* inhibit further attempts */
         }
      } else {
         /* could not get root */
         WARN("siproxd not started as root - cannot set DSCP value");
         configuration.rtp_dscp = 0; /* inhibit further attempts */
      }
      /* drop privileges */
      if (uid != euid) seteuid(euid);
   }

   /* write entry into rtp_proxytable slot (freeidx) */
   rtp_proxytable[freeidx].rtp_rx_sock=sock;

   if (callid->number) {
      strcpy(rtp_proxytable[freeidx].callid_number, callid->number);
   } else {
      rtp_proxytable[freeidx].callid_number[0]='\0';
   }

   if (callid->host) {
      strcpy(rtp_proxytable[freeidx].callid_host, callid->host);
   } else {
      rtp_proxytable[freeidx].callid_host[0]='\0';
   }

   if (client_id) {
      strcpy(rtp_proxytable[freeidx].client_id, client_id);
   } else {
      rtp_proxytable[freeidx].client_id[0]='\0';
   }

   rtp_proxytable[freeidx].direction = rtp_direction;
   rtp_proxytable[freeidx].media_stream_no = media_stream_no;
   memcpy(&rtp_proxytable[freeidx].local_ipaddr,
          &local_ipaddr, sizeof(struct in_addr));
   rtp_proxytable[freeidx].local_port=port;
   memcpy(&rtp_proxytable[freeidx].remote_ipaddr,
          &remote_ipaddr, sizeof(struct in_addr));
   rtp_proxytable[freeidx].remote_port=remote_port;
   time(&rtp_proxytable[freeidx].timestamp);

   *local_port=port;

   /* call to firewall API */
   fwapi_start_rtp(rtp_proxytable[freeidx].direction,
                   rtp_proxytable[freeidx].local_ipaddr,
                   rtp_proxytable[freeidx].local_port,
                   rtp_proxytable[freeidx].remote_ipaddr,
                   rtp_proxytable[freeidx].remote_port);

   /* prepare FD set for next select operation */
   rtp_recreate_fdset();

   /* wakeup/signal rtp_proxythread from select() hibernation */
   if (!pthread_equal(rtpproxy_tid, pthread_self()))
      pthread_kill(rtpproxy_tid, SIGALRM);

unlock_and_exit:
   /* unlock mutex */
   pthread_mutex_unlock(&rtp_proxytable_mutex);
   #undef return

   return sts;
}
コード例 #3
0
ファイル: sock.c プロジェクト: samm-git/e3372h-vendor-src
/*
 * binds to SIP UDP socket for listening to incoming packets
 *
 * RETURNS
 *	STS_SUCCESS on success
 *	STS_FAILURE on error
 */
int sipsock_listen (void) {
   struct in_addr ipaddr;
   
   /* start of AU4D00875 by d00107688 to support bind 2008-10-15*/
   struct in_addr wanipaddr;
   /* end of AU4D00875 by d00107688 to support bind 2008-10-15*/

    int i = 0;
   memset(&ipaddr, 0, sizeof(ipaddr));
   /* start of AU4D00875 by d00107688 to support bind 2008-10-15*/
   memset(&wanipaddr, 0, sizeof(wanipaddr));


    if (STS_FAILURE == get_ip_by_ifname(configuration.outbound_if, &wanipaddr))
    {
        ERROR("%s ip: %s", configuration.inbound_if, utils_inet_ntoa(wanipaddr));
        ERROR("can not get the ip , please check it.......");
    }
    else
    {
        g_lsockFlg = 1;
    }
   /* end of AU4D00875 by d00107688 to support bind 2008-10-15*/
   /* start of AU4D00875 by d00107688 to support bind 2008-10-15*/
    if (1 == g_lsockFlg)
    {
   sip_udp_socket = sockbind(ipaddr, configuration.sip_listen_port, 1);
   sip_udp_wan_socket = sockbind(wanipaddr, wanport, 1);
       if (0 == sip_udp_wan_socket)
       {
            for (i = 0; i < 5; i++)
            {
                wanport += (i * 10 + i);
                sip_udp_wan_socket = sockbind(wanipaddr, wanport, 1);
                if (0 == sip_udp_wan_socket)
                {
                    ERROR("bind in port: %d error", wanport);
                    continue;
                }
                else
                {
                    break;
                }
            }
       }
       if ((0 == sip_udp_socket) || (0 == sip_udp_wan_socket)) 
       {
            ERROR("socket bind error");
            return STS_FAILURE; /* failure */
       }
    }
    else
    {
        sip_udp_socket = sockbind(ipaddr, configuration.sip_listen_port, 1);   
   if (sip_udp_socket == 0) return STS_FAILURE; /* failure*/
    }

   INFO("bound to port %i", configuration.sip_listen_port);
   DEBUGC(DBCLASS_NET,"bound socket %i",sip_udp_socket);
   /* end of AU4D00875 by d00107688 to support bind 2008-10-15*/
   return STS_SUCCESS;
}