⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 su_proxy.c

📁 this is simple sip stack.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005 Nokia Corporation. * * Contact: Pekka Pessi <pekka.pessi@nokia.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * *//**@ingroup su_root_ex * * @file su_proxy.c  * * @brief Transport level proxy demonstrating various @b su features. * * @author Pekka Pessi <Pekka.Pessi@nokia.com> *  * @date Created: Wed May 23 17:42:40 2001 ppessi */#include "config.h"#include <stdio.h>#include <string.h>#include <stdlib.h>#include <stddef.h>#include <errno.h>#include <assert.h>typedef struct proxy_s proxy_t;typedef struct forwarder_s forwarder_t;typedef struct buffer_s buffer_t;#define SU_ROOT_MAGIC_T proxy_t#define SU_MSG_ARG_T    su_socket_t#define SU_WAKEUP_ARG_T forwarder_t#include "sofia-sip/su.h"#include "sofia-sip/su_wait.h"#include "sofia-sip/su_alloc.h"#include "su_module_debug.h"#if HAVE_FUNC#elif HAVE_FUNCTION#define __func__ __FUNCTION__#else#define __func__ "su_proxy"#endifstruct proxy_s {  su_home_t      pr_home[1];  su_root_t     *pr_root;  su_addrinfo_t *pr_addrinfo;  forwarder_t   *pr_forwarders;};struct forwarder_s {  forwarder_t  *f_next;  forwarder_t **f_prev;  proxy_t      *f_pr;  su_socket_t   f_socket;  su_wait_t     f_wait[2];  forwarder_t  *f_peer;  su_sockaddr_t f_dest[1];  buffer_t     *f_buf;  unsigned long f_sent;		/* bytes sent */  unsigned      f_shutdown : 1;  unsigned      f_upstream : 1;};struct buffer_s{  buffer_t  *b_next;  buffer_t **b_prev;  int        b_sent;  int        b_used;  char       b_data[8192];};char const help[] ="usage: su_proxy [-ntu] remotehost remoteport [localport]\n";void usage(void){  fputs(help, stderr);}static int pr_init(proxy_t *pr);static int pr_config(proxy_t *pr, int argc, char *argv[]);static int pr_run(proxy_t *pr);static void pr_deinit(proxy_t *pr);static forwarder_t *forwarder_create(proxy_t *pr);static forwarder_t *forwarder_create_listener(proxy_t *pr, su_addrinfo_t *ai);static void forwarder_deinit(forwarder_t *f);static int forwarder_init_stream(forwarder_t *f);static int forwarder_init_dgram(forwarder_t *f);static int forwarder_accept(proxy_t *pr, su_wait_t *w, forwarder_t *f);static int forwarder_stream_peer(proxy_t *pr, forwarder_t *f);static int forwarder_connected(proxy_t *pr, su_wait_t *w, forwarder_t *f);static int forwarder_recv(proxy_t *pr, su_wait_t *w, forwarder_t *f);static int forwarder_send(proxy_t *pr, forwarder_t *f, buffer_t *b);static int forwarder_append(forwarder_t *f, buffer_t *b0);static int forwarder_empty(proxy_t *pr, su_wait_t *w, forwarder_t *f);static int forwarder_shutdown(forwarder_t *f);static void forwarder_close(forwarder_t *f1);int main(int argc, char *argv[]){  proxy_t pr[1] = {{{ SU_HOME_INIT(pr) }}};  int error;  error = pr_init(pr);  if (error == 0) {    if ((error = pr_config(pr, argc, argv)) > 1)      usage();  }  if (error == 0)    error = pr_run(pr);  pr_deinit(pr);     su_deinit();  exit(error);}int pr_init(proxy_t *pr){  su_init();  su_home_init(pr->pr_home);  pr->pr_root = su_root_create(pr);  return pr->pr_root ? 0 : 1;}int pr_config(proxy_t *pr, int argc, char *argv[]){  su_addrinfo_t *res = NULL, *ai, hints[1] = {{ 0 }};  char *service;  int error;  char const *option;  /* char const *argv0 = argv[0]; */  while (argv[1][0] == '-') {    option = argv[1];    argv++, argc--;    if (strcmp(option, "--") == 0)      break;    else if (strcmp(option, "-n") == 0) {      hints->ai_flags |= AI_NUMERICHOST;    }    else if (strcmp(option, "-d") == 0) {      hints->ai_socktype = SOCK_DGRAM;    }    else if (strcmp(option, "-s") == 0) {      hints->ai_socktype = SOCK_STREAM;    }    else if (strcmp(option, "-4") == 0) {      hints->ai_family = AF_INET;    }#if SU_HAVE_IN6    else if (strcmp(option, "-6") == 0) {      hints->ai_family = AF_INET6;    }#endif  }  if (argc < 3)    return 2;  if ((error = su_getaddrinfo(argv[1], argv[2], hints, &res))) {    fprintf(stderr, "getaddrinfo: %s:%s: %s\n", 	    argv[1], argv[2], su_gai_strerror(error));    return 1;  }    pr->pr_addrinfo = res;  if (argv[3])     service = argv[3];  else    service = argv[2];  hints->ai_flags |= AI_PASSIVE;  if ((error = su_getaddrinfo(NULL, service, hints, &res))) {    fprintf(stderr, "getaddrinfo: %s: %s\n", service, su_gai_strerror(error));    return 1;  }  for (ai = res;        ai;       ai = ai->ai_next) {    forwarder_create_listener(pr, ai);  }  su_freeaddrinfo(res);    if (!pr->pr_forwarders) {    fprintf(stderr, "%s:%s: %s\n", argv[1], argv[2], "unable to forward");    return 1;  }  return 0;}void pr_deinit(proxy_t *pr){  if (pr->pr_addrinfo)    su_freeaddrinfo(pr->pr_addrinfo), pr->pr_addrinfo = NULL;  if (pr->pr_root)    su_root_destroy(pr->pr_root), pr->pr_root = NULL;  su_home_deinit(pr->pr_home);    su_deinit();}static int pr_run(proxy_t *pr){  su_root_run(pr->pr_root);  return 0;}forwarder_t *forwarder_create(proxy_t *pr){  forwarder_t *f;  assert(pr);  f = su_zalloc(pr->pr_home, sizeof (*f));  if (f) {    f->f_socket = INVALID_SOCKET;    su_wait_init(f->f_wait);    su_wait_init(f->f_wait + 1);    f->f_pr = pr;    if ((f->f_next = pr->pr_forwarders))      f->f_next->f_prev = &f->f_next;    f->f_prev = &pr->pr_forwarders;    pr->pr_forwarders = f;  }  return f;}void forwarder_destroy(forwarder_t *f){  if (f) {    forwarder_deinit(f);    if (f->f_peer) {      f->f_peer->f_peer = NULL;      forwarder_destroy(f->f_peer);      f->f_peer = NULL;    }    assert(f->f_prev);    if ((*f->f_prev = f->f_next))      f->f_next->f_prev = f->f_prev;    su_free(f->f_pr->pr_home, f);  }}void forwarder_deinit(forwarder_t *f){  su_root_unregister(f->f_pr->pr_root, f->f_wait, NULL, f);  su_wait_destroy(f->f_wait);  su_root_unregister(f->f_pr->pr_root, f->f_wait + 1, NULL, f);  su_wait_destroy(f->f_wait + 1);  if (f->f_socket != INVALID_SOCKET)    su_close(f->f_socket), f->f_socket = INVALID_SOCKET;  if (f->f_buf)    su_free(f->f_pr->pr_home, f->f_buf), f->f_buf = NULL;}static forwarder_t *forwarder_create_listener(proxy_t *pr, su_addrinfo_t *ai){  forwarder_t *f;  su_socket_t s;  if (ai->ai_socktype != SOCK_STREAM &&      ai->ai_socktype != SOCK_DGRAM)    return NULL;  f = forwarder_create(pr);  if (f) {    s = su_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);    if (s != INVALID_SOCKET) {      f->f_socket = s;      su_setblocking(s, 0);      su_setreuseaddr(s, 1);      if (bind(s, ai->ai_addr, ai->ai_addrlen) >= 0) {	if (ai->ai_socktype == SOCK_STREAM ? 	    forwarder_init_stream(f) >= 0 : 	    forwarder_init_dgram(f) >= 0)	  return f;      }      else {	SU_DEBUG_1(("%s: bind: %s\n", __func__, su_strerror(su_errno())));      }    }  }  forwarder_destroy(f);    return NULL;}int forwarder_init_stream(forwarder_t *f){  if (listen(f->f_socket, SOMAXCONN) < 0)    return SOCKET_ERROR;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -