Improve the socket option configuration (#1404)

o GTP-C Option (Default)
  - so_bindtodevice : NULL

  gtpc:
    addr: 127.0.0.7
    option:
      so_bindtodevice: vrf-blue

o GTP-U Option (Default)
  - so_bindtodevice : NULL

  gtpu:
    addr: 127.0.0.7
    option:
      so_bindtodevice: vrf-blue

o PFCP Option (Default)
  - so_bindtodevice : NULL

  pfcp:
    addr: 127.0.0.7
    option:
      so_bindtodevice: vrf-blue

o SBI Option (Default)
  - tcp_nodelay : true
  - so_linger.l_onoff : false

  sbi:
    addr: 127.0.0.10
    option:
      tcp_nodelay: false
      so_linger:
        l_onoff: true
        l_linger: 10

o NGAP Option (Default)
  - sctp_nodelay : true
  - so_linger.l_onoff : false
ngap:
  addr: 127.0.0.5
  option:
    stcp_nodelay: false
    so_linger:
      l_onoff: true
      l_linger: 10

o NGAP SCTP Option (Default)
  - spp_hbinterval : 5000 (5secs)
  - spp_sackdelay : 200 (200ms)
  - srto_initial : 3000 (3secs)
  - srto_min : 1000 (1sec)
  - srto_max : 5000 (5secs)
  - sinit_num_ostreams : 30
  - sinit_max_instreams : 65535
  - sinit_max_attempts : 4
  - sinit_max_init_timeo : 8000(8secs)
ngap:
  addr: 127.0.0.5
  option:
    sctp:
      spp_hbinterval : 5000
      spp_sackdelay : 200
      srto_initial : 3000
      srto_min : 1000
      srto_max : 5000
      sinit_num_ostreams : 30
      sinit_max_instreams : 65535
      sinit_max_attempts : 4
      sinit_max_init_timeo : 8000
This commit is contained in:
Sukchan Lee 2022-03-15 22:03:50 +09:00
parent 73836c063c
commit bcf53124d5
61 changed files with 1725 additions and 701 deletions

View File

@ -73,6 +73,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.5
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
# <NGAP Server>>
#
# o NGAP Server(all address avaiable)
@ -96,6 +108,43 @@ logger:
# ngap:
# dev: eth0
#
# o NGAP Option (Default)
# - sctp_nodelay : true
# - so_linger.l_onoff : false
#
# ngap:
# addr: 127.0.0.5
# option:
# stcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
# o NGAP SCTP Option (Default)
# - spp_hbinterval : 5000 (5secs)
# - spp_sackdelay : 200 (200ms)
# - srto_initial : 3000 (3secs)
# - srto_min : 1000 (1sec)
# - srto_max : 5000 (5secs)
# - sinit_num_ostreams : 30
# - sinit_max_instreams : 65535
# - sinit_max_attempts : 4
# - sinit_max_init_timeo : 8000(8secs)
#
# ngap:
# addr: 127.0.0.5
# option:
# sctp:
# spp_hbinterval : 5000
# spp_sackdelay : 200
# srto_initial : 3000
# srto_min : 1000
# srto_max : 5000
# sinit_num_ostreams : 30
# sinit_max_instreams : 65535
# sinit_max_attempts : 4
# sinit_max_init_timeo : 8000
#
# <GUAMI>
#
# o Multiple GUAMI
@ -232,6 +281,18 @@ amf:
# - 127.0.0.10
# - fd69:f21d:873c:fa::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
- addr:
@ -288,26 +349,10 @@ max:
pool:
#
# sockopt:
# no_delay : true
# bindtodevice : false
# usrsctp:
# udp_port : 9899
#
sockopt:
#
# sctp:
# heartbit_interval : 5000 (5secs)
# sack_delay : 200 (200ms)
# rto_initial : 3000 (3secs)
# rto_min : 1000 (1sec)
# rto_max : 5000 (5secs)
# max_num_of_ostreams : 30
# max_num_of_istreams : 65535
# max_attempts : 4
# max_initial_timeout : 8000(8secs)
# usrsctp_udp_port : 9899
#
sctp:
usrsctp:
#
# time:

View File

@ -73,6 +73,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.11
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
ausf:
sbi:
- addr: 127.0.0.11
@ -104,6 +116,18 @@ ausf:
# - 127.0.0.10
# - fd69:f21d:873c:fa::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
- addr:

View File

@ -75,6 +75,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.15
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
bsf:
sbi:
- addr: 127.0.0.15
@ -106,6 +118,18 @@ bsf:
# - 127.0.0.10
# - fd69:f21d:873c:fa::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
- addr:

View File

@ -47,6 +47,43 @@ logger:
# s1ap:
# dev: eth0
#
# o S1AP Option (Default)
# - sctp_nodelay : true
# - so_linger.l_onoff : false
#
# s1ap:
# addr: 127.0.0.2
# option:
# stcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
# o S1AP SCTP Option (Default)
# - spp_hbinterval : 5000 (5secs)
# - spp_sackdelay : 200 (200ms)
# - srto_initial : 3000 (3secs)
# - srto_min : 1000 (1sec)
# - srto_max : 5000 (5secs)
# - sinit_num_ostreams : 30
# - sinit_max_instreams : 65535
# - sinit_max_attempts : 4
# - sinit_max_init_timeo : 8000(8secs)
#
# s1ap:
# addr: 127.0.0.2
# option:
# sctp:
# spp_hbinterval : 5000
# spp_sackdelay : 200
# srto_initial : 3000
# srto_min : 1000
# srto_max : 5000
# sinit_num_ostreams : 30
# sinit_max_instreams : 65535
# sinit_max_attempts : 4
# sinit_max_init_timeo : 8000
#
# <GTP-C Server>>
#
# o GTP-C Server(all address avaiable)
@ -386,26 +423,10 @@ max:
pool:
#
# sockopt:
# no_delay : true
# bindtodevice : false
# usrsctp:
# udp_port : 9899
#
sockopt:
#
# sctp:
# heartbit_interval : 5000 (5secs)
# sack_delay : 200 (200ms)
# rto_initial : 3000 (3secs)
# rto_min : 1000 (1sec)
# rto_max : 5000 (5secs)
# max_num_of_ostreams : 30
# max_num_of_istreams : 65535
# max_attempts : 4
# max_initial_timeout : 8000(8secs)
# usrsctp_udp_port : 9899
#
sctp:
usrsctp:
#
# time:

View File

@ -65,6 +65,18 @@ logger:
# sbi:
# dev: eth0
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
addr:

View File

@ -73,6 +73,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.14
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
# <List of avaiable Network Slice Instance(NSI)>
#
# o One NSI
@ -110,6 +122,18 @@ logger:
# s_nssai:
# sst: 1
# sd: 009000
#
# o NSI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# nsi:
# addr: ::1
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
nssf:
sbi:
- addr: 127.0.0.14

View File

@ -75,6 +75,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.13
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
pcf:
sbi:
- addr: 127.0.0.13
@ -106,6 +118,18 @@ pcf:
# - 127.0.0.10
# - fd69:f21d:873c:fa::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
- addr:

View File

@ -38,6 +38,14 @@ logger:
# - addr: 127.0.0.3
# - addr: fd69:f21d:873c:fa::2
#
# o GTP-C Option (Default)
# - so_bindtodevice : NULL
#
# gtpc:
# addr: 127.0.0.3
# option:
# so_bindtodevice: vrf-blue
#
# <PFCP Server>
#
# o PFCP Server(127.0.0.3:8805, ::1:8805)
@ -49,6 +57,14 @@ logger:
# pfcp:
# name: localhost
#
# o PFCP Option (Default)
# - so_bindtodevice : NULL
#
# pfcp:
# addr: 127.0.0.3
# option:
# so_bindtodevice: vrf-blue
#
sgwc:
gtpc:
- addr: 127.0.0.3
@ -160,12 +176,6 @@ max:
#
pool:
#
# sockopt:
# bindtodevice : false
#
sockopt:
#
# time:
#

View File

@ -35,6 +35,14 @@ logger:
# pfcp:
# - name: localhost
#
# o PFCP Option (Default)
# - so_bindtodevice : NULL
#
# pfcp:
# addr: 127.0.0.6
# option:
# so_bindtodevice: vrf-blue
#
# <GTP-U Server>
#
# o GTP-U Server(127.0.0.6:2152, [::1]:2152)
@ -80,6 +88,14 @@ logger:
# - dev: ens3
# advertise: sgw1.epc.mnc001.mcc001.3gppnetwork.org
#
# o GTP-U Option (Default)
# - so_bindtodevice : NULL
#
# gtpu:
# addr: 127.0.0.6
# option:
# so_bindtodevice: vrf-blue
#
sgwu:
pfcp:
- addr: 127.0.0.6
@ -149,13 +165,6 @@ max:
#
pool:
#
# sockopt:
# no_delay : true
# bindtodevice : false
#
sockopt:
#
# time:
#

View File

@ -73,6 +73,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.4
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
# <PFCP Server>
#
# o PFCP Server(127.0.0.4:8805, ::1:8805)
@ -84,6 +96,14 @@ logger:
# pfcp:
# name: localhost
#
# o PFCP Option (Default)
# - so_bindtodevice : NULL
#
# pfcp:
# addr: 127.0.0.4
# option:
# so_bindtodevice: vrf-blue
#
# <GTP-C Server>
#
# o GTP-C Server(127.0.0.4:2123, [fd69:f21d:873c:fa::3]:2123)
@ -98,6 +118,14 @@ logger:
# - addr: 127.0.0.4
# - addr: fd69:f21d:873c:fa::3
#
# o GTP-C Option (Default)
# - so_bindtodevice : NULL
#
# gtpc:
# addr: 127.0.0.4
# option:
# so_bindtodevice: vrf-blue
#
# <GTP-U Server>>
#
# o GTP-U Server(127.0.0.4:2152, [::1]:2152)
@ -109,6 +137,14 @@ logger:
# gtpu:
# name: localhost
#
# o GTP-U Option (Default)
# - so_bindtodevice : NULL
#
# gtpu:
# addr: 127.0.0.4
# option:
# so_bindtodevice: vrf-blue
#
# <Subnet for UE Pool>
#
# o IPv4 Pool
@ -377,6 +413,18 @@ smf:
# - 127.0.0.10
# - fd69:f21d:873c:fa::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
- addr:
@ -498,12 +546,6 @@ max:
#
pool:
#
# sockopt:
# bindtodevice : false
#
sockopt:
#
# time:
#

View File

@ -73,6 +73,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.12
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
udm:
sbi:
- addr: 127.0.0.12
@ -104,6 +116,18 @@ udm:
# - 127.0.0.10
# - fd69:f21d:873c:fa::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
- addr:

View File

@ -75,6 +75,18 @@ logger:
# - 127.0.0.99
# - ::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.20
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
udr:
sbi:
- addr: 127.0.0.20
@ -106,6 +118,18 @@ udr:
# - 127.0.0.10
# - fd69:f21d:873c:fa::1
#
# o SBI Option (Default)
# - tcp_nodelay : true
# - so_linger.l_onoff : false
#
# sbi:
# addr: 127.0.0.10
# option:
# tcp_nodelay: false
# so_linger:
# l_onoff: true
# l_linger: 10
#
nrf:
sbi:
- addr:

View File

@ -35,6 +35,14 @@ logger:
# pfcp:
# name: localhost
#
# o PFCP Option (Default)
# - so_bindtodevice : NULL
#
# pfcp:
# addr: 127.0.0.7
# option:
# so_bindtodevice: vrf-blue
#
# <GTP-U Server>>
#
# o GTP-U Server(127.0.0.7:2152, [::1]:2152)
@ -80,6 +88,14 @@ logger:
# - dev: ens3
# advertise: upf1.5gc.mnc001.mcc001.3gppnetwork.org
#
# o GTP-U Option (Default)
# - so_bindtodevice : NULL
#
# gtpu:
# addr: 127.0.0.7
# option:
# so_bindtodevice: vrf-blue
#
# <Subnet for UE network>
#
# Note that you need to setup your UE network using TUN device.
@ -220,12 +236,6 @@ max:
#
pool:
#
# sockopt:
# bindtodevice : false
#
sockopt:
#
# time:
#

View File

@ -20,10 +20,12 @@ libapp_sources = files('''
ogs-yaml.h
ogs-context.h
ogs-config.h
ogs-init.h
ogs-yaml.c
ogs-context.c
ogs-config.c
ogs-init.c
'''.split())

View File

@ -28,6 +28,7 @@ extern int __ogs_app_domain;
#include "app/ogs-yaml.h"
#include "app/ogs-context.h"
#include "app/ogs-config.h"
#include "app/ogs-init.h"
#undef OGS_APP_INSIDE

110
lib/app/ogs-config.c Normal file
View File

@ -0,0 +1,110 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "ogs-app.h"
int ogs_app_config_parse_sockopt(
ogs_yaml_iter_t *parent, ogs_sockopt_t *option)
{
ogs_yaml_iter_t sockopt_iter;
ogs_assert(parent);
ogs_assert(option);
ogs_sockopt_init(option);
ogs_yaml_iter_recurse(parent, &sockopt_iter);
while (ogs_yaml_iter_next(&sockopt_iter)) {
const char *sockopt_key = ogs_yaml_iter_key(&sockopt_iter);
ogs_assert(sockopt_key);
if (!strcmp(sockopt_key, "sctp")) {
ogs_yaml_iter_t sctp_iter;
ogs_yaml_iter_recurse(&sockopt_iter, &sctp_iter);
while (ogs_yaml_iter_next(&sctp_iter)) {
const char *sctp_key = ogs_yaml_iter_key(&sctp_iter);
ogs_assert(sctp_key);
if (!strcmp(sctp_key, "spp_hbinterval")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.spp_hbinterval = atoi(v);
} else if (!strcmp(sctp_key, "spp_sackdelay")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.spp_sackdelay = atoi(v);
} else if (!strcmp(sctp_key, "srto_initial")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.srto_initial = atoi(v);
} else if (!strcmp(sctp_key, "srto_min")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.srto_min = atoi(v);
} else if (!strcmp(sctp_key, "srto_max")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.srto_max = atoi(v);
} else if (!strcmp(sctp_key, "sinit_num_ostreams")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.sinit_num_ostreams = atoi(v);
} else if (!strcmp(sctp_key, "sinit_max_instreams")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.sinit_max_instreams = atoi(v);
} else if (!strcmp(sctp_key, "sinit_max_attempts")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.sinit_max_attempts = atoi(v);
} else if (!strcmp(sctp_key, "sinit_max_init_timeo")) {
const char *v = ogs_yaml_iter_value(&sctp_iter);
if (v) option->sctp.sinit_max_init_timeo = atoi(v);
} else {
ogs_error("unknown key `%s`", sctp_key);
return OGS_ERROR;
}
}
} else if (!strcmp(sockopt_key, "sctp_nodelay")) {
option->sctp_nodelay = ogs_yaml_iter_bool(&sockopt_iter);
} else if (!strcmp(sockopt_key, "tcp_nodelay")) {
option->tcp_nodelay = ogs_yaml_iter_bool(&sockopt_iter);
} else if (!strcmp(sockopt_key, "so_linger")) {
ogs_yaml_iter_t so_linger_iter;
ogs_yaml_iter_recurse(&sockopt_iter, &so_linger_iter);
while (ogs_yaml_iter_next(&so_linger_iter)) {
const char *so_linger_key = ogs_yaml_iter_key(&so_linger_iter);
ogs_assert(so_linger_key);
if (!strcmp(so_linger_key, "l_onoff")) {
option->so_linger.l_onoff =
ogs_yaml_iter_bool(&so_linger_iter);
} else if (!strcmp(so_linger_key, "l_linger")) {
const char *v = ogs_yaml_iter_value(&so_linger_iter);
if (v) option->so_linger.l_linger = atoi(v);
} else {
ogs_error("unknown key `%s`", so_linger_key);
return OGS_ERROR;
}
}
} else if (!strcmp(sockopt_key, "so_bindtodevice")) {
option->so_bindtodevice = ogs_yaml_iter_value(&sockopt_iter);
} else {
ogs_error("unknown key `%s`", sockopt_key);
return OGS_ERROR;
}
}
return OGS_OK;
}

38
lib/app/ogs-config.h Normal file
View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
#if !defined(OGS_APP_INSIDE) && !defined(OGS_APP_COMPILATION)
#error "This header cannot be included directly."
#endif
#ifndef OGS_APP_CONFIG_H
#define OGS_APP_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
int ogs_app_config_parse_sockopt(
ogs_yaml_iter_t *parent, ogs_sockopt_t *sockopt);
#ifdef __cplusplus
}
#endif
#endif /* OGS_APP_CONFIG_H */

View File

@ -187,7 +187,6 @@ static void app_context_prepare(void)
self.sctp.max_initial_timeout = 8000; /* 8 seconds */
self.sockopt.no_delay = true;
self.sockopt.bindtodevice = false;
#define MAX_NUM_OF_UE 1024 /* Num of UE per AMF/MME */
#define MAX_NUM_OF_GNB 64 /* Num of gNB per AMF/MME */
@ -377,9 +376,6 @@ int ogs_app_context_parse_config(void)
const char *v = ogs_yaml_iter_value(&sockopt_iter);
if (v) self.sockopt.l_linger = atoi(v);
self.sockopt.l_onoff = true;
} else if (!strcmp(sockopt_key, "bindtodevice")) {
self.sockopt.bindtodevice =
ogs_yaml_iter_bool(&sockopt_iter);
} else
ogs_warn("unknown key `%s`", sockopt_key);
}

View File

@ -24,8 +24,6 @@
#ifndef OGS_APP_CONTEXT_H
#define OGS_APP_CONTEXT_H
#include "ogs-app.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -84,7 +82,6 @@ typedef struct ogs_app_context_s {
int no_delay;
int l_onoff;
int l_linger;
int bindtodevice;
} sockopt;
struct {

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "ogs-yaml.h"
#include "ogs-app.h"
void ogs_yaml_iter_init(ogs_yaml_iter_t *iter, yaml_document_t *document)
{

View File

@ -26,8 +26,6 @@
#include <yaml.h>
#include "ogs-app.h"
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -241,6 +241,7 @@ libcore_sources = files('''
ogs-process.h
ogs-sockaddr.h
ogs-socket.h
ogs-sockopt.h
ogs-sockpair.h
ogs-socknode.h
ogs-udp.h
@ -275,6 +276,7 @@ libcore_sources = files('''
ogs-process.c
ogs-sockaddr.c
ogs-socket.c
ogs-sockopt.c
ogs-sockpair.c
ogs-socknode.c
ogs-udp.c

View File

@ -47,6 +47,7 @@
#include "core/ogs-signal.h"
#include "core/ogs-sockaddr.h"
#include "core/ogs-socket.h"
#include "core/ogs-sockopt.h"
#include "core/ogs-sockpair.h"
#include "core/ogs-socknode.h"
#include "core/ogs-udp.h"

View File

@ -255,102 +255,3 @@ int ogs_closesocket(ogs_socket_t fd)
return OGS_OK;
}
int ogs_nonblocking(ogs_socket_t fd)
{
#ifdef _WIN32
int rc;
ogs_assert(fd != INVALID_SOCKET);
u_long io_mode = 1;
rc = ioctlsocket(fd, FIONBIO, &io_mode);
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "ioctlsocket failed");
return OGS_ERROR;
}
#else
int rc;
int flags;
ogs_assert(fd != INVALID_SOCKET);
flags = fcntl(fd, F_GETFL, NULL);
if (flags < 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_GETFL failed");
return OGS_ERROR;
}
if (!(flags & O_NONBLOCK)) {
rc = fcntl(fd, F_SETFL, (flags | O_NONBLOCK));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_SETFL failed");
return OGS_ERROR;
}
}
#endif
return OGS_OK;
}
int ogs_closeonexec(ogs_socket_t fd)
{
#ifndef _WIN32
int rc;
int flags;
ogs_assert(fd != INVALID_SOCKET);
flags = fcntl(fd, F_GETFD, NULL);
if (flags < 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_GETFD failed");
return OGS_ERROR;
}
if (!(flags & FD_CLOEXEC)) {
rc = fcntl(fd, F_SETFD, (flags | FD_CLOEXEC));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_SETFD failed");
return OGS_ERROR;
}
}
#endif
return OGS_OK;
}
int ogs_listen_reusable(ogs_socket_t fd)
{
#if defined(SO_REUSEADDR) && !defined(_WIN32)
int rc;
int on = 1;
ogs_assert(fd != INVALID_SOCKET);
rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(int));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"setsockopt(SOL_SOCKET, SO_REUSEADDR) failed");
return OGS_ERROR;
}
#endif
return OGS_OK;
}
int ogs_bind_to_device(ogs_socket_t fd, const char *device)
{
#if defined(SO_BINDTODEVICE) && !defined(_WIN32)
int rc;
ogs_assert(fd != INVALID_SOCKET);
ogs_assert(device);
rc = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1);
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"setsockopt(SOL_SOCKET, SO_BINDTODEVICE, %s) failed", device);
ogs_error("You need to grant privileges to use SO_BINDTODEVICE.");
ogs_error("OR disable SO_BINDTODEVICE "
"in the configuration file as below.");
ogs_log_print(OGS_LOG_ERROR, "\nsockopt:\n");
ogs_log_print(OGS_LOG_ERROR, " bindtodevice : false\n\n");
return OGS_ERROR;
}
#endif
return OGS_OK;
}

View File

@ -71,11 +71,6 @@ ssize_t ogs_recvfrom(ogs_socket_t fd,
int ogs_closesocket(ogs_socket_t fd);
int ogs_nonblocking(ogs_socket_t fd);
int ogs_closeonexec(ogs_socket_t fd);
int ogs_listen_reusable(ogs_socket_t fd);
int ogs_bind_to_device(ogs_socket_t fd, const char *device);
#ifdef __cplusplus
}
#endif

View File

@ -61,11 +61,13 @@ void ogs_socknode_free(ogs_socknode_t *node)
else
ogs_sock_destroy(node->sock);
}
if (node->option)
ogs_free(node->option);
ogs_free(node);
}
ogs_socknode_t *ogs_socknode_add(
ogs_list_t *list, int family, ogs_sockaddr_t *addr)
ogs_socknode_t *ogs_socknode_add(ogs_list_t *list,
int family, ogs_sockaddr_t *addr, ogs_sockopt_t *option)
{
ogs_socknode_t *node = NULL;
ogs_sockaddr_t *dup = NULL;
@ -81,6 +83,9 @@ ogs_socknode_t *ogs_socknode_add(
node = ogs_socknode_new(dup);
ogs_assert(node);
ogs_list_add(list, node);
if (option)
node->option = ogs_memdup(option, sizeof *option);
}
return node;
@ -102,8 +107,8 @@ void ogs_socknode_remove_all(ogs_list_t *list)
ogs_socknode_remove(list, node);
}
int ogs_socknode_probe(
ogs_list_t *list, ogs_list_t *list6, const char *dev, uint16_t port)
int ogs_socknode_probe(ogs_list_t *list, ogs_list_t *list6,
const char *dev, uint16_t port, ogs_sockopt_t *option)
{
#if defined(HAVE_GETIFADDRS)
ogs_socknode_t *node = NULL;
@ -177,6 +182,9 @@ int ogs_socknode_probe(
ogs_list_add(list6, node);
} else
ogs_assert_if_reached();
if (option)
node->option = ogs_memdup(option, sizeof *option);
}
freeifaddrs(iflist);
@ -190,6 +198,7 @@ int ogs_socknode_probe(
}
#if 0 /* deprecated */
int ogs_socknode_fill_scope_id_in_local(ogs_sockaddr_t *sa_list)
{
#if defined(HAVE_GETIFADDRS)
@ -247,6 +256,7 @@ int ogs_socknode_fill_scope_id_in_local(ogs_sockaddr_t *sa_list)
return OGS_ERROR;
#endif
}
#endif
void ogs_socknode_set_cleanup(
ogs_socknode_t *node, void (*cleanup)(ogs_sock_t *))

View File

@ -35,24 +35,28 @@ typedef struct ogs_socknode_s {
ogs_lnode_t node;
ogs_sockaddr_t *addr;
char *dev; /* !NULL: used with SO_BINDTODEVICE */
char *dev;
ogs_sock_t *sock;
void (*cleanup)(ogs_sock_t *sock);
ogs_poll_t *poll;
ogs_sockopt_t *option;
} ogs_socknode_t;
ogs_socknode_t *ogs_socknode_new(ogs_sockaddr_t *addr);
void ogs_socknode_free(ogs_socknode_t *node);
ogs_socknode_t *ogs_socknode_add(
ogs_list_t *list, int family, ogs_sockaddr_t *sa_list);
ogs_socknode_t *ogs_socknode_add(ogs_list_t *list,
int family, ogs_sockaddr_t *addr, ogs_sockopt_t *option);
void ogs_socknode_remove(ogs_list_t *list, ogs_socknode_t *node);
void ogs_socknode_remove_all(ogs_list_t *list);
int ogs_socknode_probe(
ogs_list_t *list, ogs_list_t *list6, const char *dev, uint16_t port);
int ogs_socknode_probe(ogs_list_t *list, ogs_list_t *list6,
const char *dev, uint16_t port, ogs_sockopt_t *option);
#if 0 /* deprecated */
int ogs_socknode_fill_scope_id_in_local(ogs_sockaddr_t *sa_list);
#endif
void ogs_socknode_set_cleanup(
ogs_socknode_t *node, void (*cleanup)(ogs_sock_t *));

195
lib/core/ogs-sockopt.c Normal file
View File

@ -0,0 +1,195 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "core-config-private.h"
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#if HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#include "ogs-core.h"
#undef OGS_LOG_DOMAIN
#define OGS_LOG_DOMAIN __ogs_sock_domain
void ogs_sockopt_init(ogs_sockopt_t *option)
{
ogs_assert(option);
memset(option, 0, sizeof *option);
option->sctp.spp_hbinterval = 5000; /* 5 seconds */
option->sctp.spp_sackdelay = 200; /* 200 ms */
option->sctp.srto_initial = 3000; /* 3 seconds */
option->sctp.srto_min = 1000; /* 1 seconds */
option->sctp.srto_max = 5000; /* 5 seconds */
option->sctp.sinit_num_ostreams = OGS_DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS;
option->sctp.sinit_max_instreams = 65535;
option->sctp.sinit_max_attempts = 4;
option->sctp.sinit_max_init_timeo = 8000; /* 8 seconds */
option->sctp_nodelay = true;
option->tcp_nodelay = true;
}
int ogs_nonblocking(ogs_socket_t fd)
{
#ifdef _WIN32
int rc;
ogs_assert(fd != INVALID_SOCKET);
u_long io_mode = 1;
rc = ioctlsocket(fd, FIONBIO, &io_mode);
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "ioctlsocket failed");
return OGS_ERROR;
}
#else
int rc;
int flags;
ogs_assert(fd != INVALID_SOCKET);
flags = fcntl(fd, F_GETFL, NULL);
if (flags < 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_GETFL failed");
return OGS_ERROR;
}
if (!(flags & O_NONBLOCK)) {
rc = fcntl(fd, F_SETFL, (flags | O_NONBLOCK));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_SETFL failed");
return OGS_ERROR;
}
}
#endif
return OGS_OK;
}
int ogs_closeonexec(ogs_socket_t fd)
{
#ifndef _WIN32
int rc;
int flags;
ogs_assert(fd != INVALID_SOCKET);
flags = fcntl(fd, F_GETFD, NULL);
if (flags < 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_GETFD failed");
return OGS_ERROR;
}
if (!(flags & FD_CLOEXEC)) {
rc = fcntl(fd, F_SETFD, (flags | FD_CLOEXEC));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "F_SETFD failed");
return OGS_ERROR;
}
}
#endif
return OGS_OK;
}
int ogs_listen_reusable(ogs_socket_t fd, int on)
{
#if defined(SO_REUSEADDR) && !defined(_WIN32)
int rc;
ogs_assert(fd != INVALID_SOCKET);
ogs_debug("Turn on SO_REUSEADDR");
rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(int));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"setsockopt(SOL_SOCKET, SO_REUSEADDR) failed");
return OGS_ERROR;
}
#endif
return OGS_OK;
}
int ogs_tcp_nodelay(ogs_socket_t fd, int on)
{
#if defined(TCP_NODELAY) && !defined(_WIN32)
int rc;
ogs_assert(fd != INVALID_SOCKET);
ogs_debug("Turn on TCP_NODELAY");
rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(int));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"setsockopt(IPPROTO_TCP, TCP_NODELAY) failed");
return OGS_ERROR;
}
#endif
return OGS_OK;
}
int ogs_so_linger(ogs_socket_t fd, int l_linger)
{
#if defined(SO_LINGER) && !defined(_WIN32)
struct linger l;
int rc;
ogs_assert(fd != INVALID_SOCKET);
memset(&l, 0, sizeof(l));
l.l_onoff = 1;
l.l_linger = l_linger;
ogs_debug("SO_LINGER:[%d]", l_linger);
rc = setsockopt(fd, SOL_SOCKET, SO_LINGER,
(void *)&l, sizeof(struct linger));
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"setsockopt(SOL_SOCKET, SO_LINGER) failed");
return OGS_ERROR;
}
#endif
return OGS_OK;
}
int ogs_bind_to_device(ogs_socket_t fd, const char *device)
{
#if defined(SO_BINDTODEVICE) && !defined(_WIN32)
int rc;
ogs_assert(fd != INVALID_SOCKET);
ogs_assert(device);
ogs_debug("SO_BINDTODEVICE:[%s]", device);
rc = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1);
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"setsockopt(SOL_SOCKET, SO_BINDTODEVICE, %s) failed", device);
ogs_error("You need to grant privileges to use SO_BINDTODEVICE.");
return OGS_ERROR;
}
#endif
return OGS_OK;
}

68
lib/core/ogs-sockopt.h Normal file
View File

@ -0,0 +1,68 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
#if !defined(OGS_CORE_INSIDE) && !defined(OGS_CORE_COMPILATION)
#error "This header cannot be included directly."
#endif
#ifndef OGS_SOCKOPT_H
#define OGS_SOCKOPT_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ogs_sockopt_s {
struct {
uint32_t spp_hbinterval;
uint32_t spp_sackdelay;
uint32_t srto_initial;
uint32_t srto_min;
uint32_t srto_max;
uint16_t sinit_num_ostreams;
uint16_t sinit_max_instreams;
uint16_t sinit_max_attempts;
uint16_t sinit_max_init_timeo;
} sctp;
bool sctp_nodelay;
bool tcp_nodelay;
struct {
bool l_onoff;
int l_linger;
} so_linger;
const char *so_bindtodevice;
} ogs_sockopt_t;
void ogs_sockopt_init(ogs_sockopt_t *option);
int ogs_nonblocking(ogs_socket_t fd);
int ogs_closeonexec(ogs_socket_t fd);
int ogs_listen_reusable(ogs_socket_t fd, int on);
int ogs_tcp_nodelay(ogs_socket_t fd, int on);
int ogs_so_linger(ogs_socket_t fd, int l_linger);
int ogs_bind_to_device(ogs_socket_t fd, const char *device);
#ifdef __cplusplus
}
#endif
#endif /* OGS_SOCKOPT_H */

View File

@ -22,21 +22,38 @@
#undef OGS_LOG_DOMAIN
#define OGS_LOG_DOMAIN __ogs_sock_domain
ogs_sock_t *ogs_tcp_server(ogs_socknode_t *node)
ogs_sock_t *ogs_tcp_server(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
{
int rv;
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
char buf[OGS_ADDRSTRLEN];
ogs_assert(node);
ogs_assert(node->addr);
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
ogs_sockopt_t option;
addr = node->addr;
ogs_assert(sa_list);
ogs_sockopt_init(&option);
if (socket_option)
memcpy(&option, socket_option, sizeof option);
addr = sa_list;
while(addr) {
new = ogs_sock_socket(addr->ogs_sa_family, SOCK_STREAM, IPPROTO_TCP);
if (new) {
rv = ogs_listen_reusable(new->fd);
if (option.tcp_nodelay == true) {
rv = ogs_tcp_nodelay(new->fd, true);
ogs_assert(rv == OGS_OK);
} else
ogs_warn("TCP NO_DELAY Disabled");
if (option.so_linger.l_onoff == true) {
rv = ogs_so_linger(new->fd, option.so_linger.l_linger);
ogs_assert(rv == OGS_OK);
}
rv = ogs_listen_reusable(new->fd, true);
ogs_assert(rv == OGS_OK);
if (ogs_sock_bind(new, addr) == OGS_OK) {
@ -54,31 +71,47 @@ ogs_sock_t *ogs_tcp_server(ogs_socknode_t *node)
if (addr == NULL) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"tcp_server() [%s]:%d failed",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
return NULL;
}
rv = ogs_sock_listen(new);
ogs_assert(rv == OGS_OK);
node->sock = new;
return new;
}
ogs_sock_t *ogs_tcp_client(ogs_socknode_t *node)
ogs_sock_t *ogs_tcp_client(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
{
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
int rv;
char buf[OGS_ADDRSTRLEN];
ogs_assert(node);
ogs_assert(node->addr);
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
ogs_sockopt_t option;
addr = node->addr;
ogs_assert(sa_list);
ogs_sockopt_init(&option);
if (socket_option)
memcpy(&option, socket_option, sizeof option);
addr = sa_list;
while (addr) {
new = ogs_sock_socket(addr->ogs_sa_family, SOCK_STREAM, IPPROTO_TCP);
if (new) {
if (option.sctp_nodelay == true) {
rv = ogs_tcp_nodelay(new->fd, true);
ogs_assert(rv == OGS_OK);
} else
ogs_warn("TCP NO_DELAY Disabled");
if (option.so_linger.l_onoff == true) {
rv = ogs_so_linger(new->fd, option.so_linger.l_linger);
ogs_assert(rv == OGS_OK);
}
if (ogs_sock_connect(new, addr) == OGS_OK) {
ogs_debug("tcp_client() [%s]:%d",
OGS_ADDR(addr, buf), OGS_PORT(addr));
@ -94,11 +127,9 @@ ogs_sock_t *ogs_tcp_client(ogs_socknode_t *node)
if (addr == NULL) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"tcp_client() [%s]:%d failed",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
return NULL;
}
node->sock = new;
return new;
}

View File

@ -28,8 +28,10 @@
extern "C" {
#endif
ogs_sock_t *ogs_tcp_server(ogs_socknode_t *node);
ogs_sock_t *ogs_tcp_client(ogs_socknode_t *node);
ogs_sock_t *ogs_tcp_server(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option);
ogs_sock_t *ogs_tcp_client(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option);
#ifdef __cplusplus
}

View File

@ -22,29 +22,24 @@
#undef OGS_LOG_DOMAIN
#define OGS_LOG_DOMAIN __ogs_sock_domain
ogs_sock_t *ogs_udp_socket(int family, ogs_socknode_t *node)
ogs_sock_t *ogs_udp_server(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
{
ogs_sock_t *sock = NULL;
sock = ogs_sock_socket(family, SOCK_DGRAM, IPPROTO_UDP);
ogs_assert(sock);
ogs_debug("udp_socket() family:%d", family);
return sock;
}
ogs_sock_t *ogs_udp_server(ogs_socknode_t *node, bool bindtodevice)
{
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
char buf[OGS_ADDRSTRLEN];
ogs_assert(node);
ogs_assert(node->addr);
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
ogs_sockopt_t option;
addr = node->addr;
ogs_assert(sa_list);
ogs_sockopt_init(&option);
if (socket_option)
memcpy(&option, socket_option, sizeof option);
addr = sa_list;
while (addr) {
new = ogs_udp_socket(addr->ogs_sa_family, node);
new = ogs_sock_socket(addr->ogs_sa_family, SOCK_DGRAM, IPPROTO_UDP);
if (!new) {
addr = addr->next;
continue;
@ -55,14 +50,15 @@ ogs_sock_t *ogs_udp_server(ogs_socknode_t *node, bool bindtodevice)
continue;
}
ogs_debug("udp_server() [%s]:%d", OGS_ADDR(addr, buf), OGS_PORT(addr));
if (bindtodevice == true && node->dev) {
if (ogs_bind_to_device(new->fd, node->dev) != OGS_OK) {
if (option.so_bindtodevice) {
if (ogs_bind_to_device(new->fd, option.so_bindtodevice) != OGS_OK) {
ogs_sock_destroy(new);
addr = addr->next;
continue;
}
ogs_debug("udp_server() [%s]:%d bound to device %s",
OGS_ADDR(addr, buf), OGS_PORT(addr), node->dev);
ogs_info("udp_server() [%s]:%d bound to device `%s`",
OGS_ADDR(addr, buf), OGS_PORT(addr),
option.so_bindtodevice);
}
break;
}
@ -70,27 +66,32 @@ ogs_sock_t *ogs_udp_server(ogs_socknode_t *node, bool bindtodevice)
if (addr == NULL) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"udp_server() [%s]:%d failed",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
return NULL;
}
node->sock = new;
return new;
}
ogs_sock_t *ogs_udp_client(ogs_socknode_t *node)
ogs_sock_t *ogs_udp_client(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
{
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
char buf[OGS_ADDRSTRLEN];
ogs_assert(node);
ogs_assert(node->addr);
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
addr = node->addr;
ogs_sockopt_t option;
ogs_assert(sa_list);
ogs_sockopt_init(&option);
if (socket_option)
memcpy(&option, socket_option, sizeof option);
addr = sa_list;
while (addr) {
new = ogs_udp_socket(addr->ogs_sa_family, node);
new = ogs_sock_socket(addr->ogs_sa_family, SOCK_DGRAM, IPPROTO_UDP);
if (new) {
if (ogs_sock_connect(new, addr) == OGS_OK) {
ogs_debug("udp_client() [%s]:%d",
@ -107,12 +108,10 @@ ogs_sock_t *ogs_udp_client(ogs_socknode_t *node)
if (addr == NULL) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"udp_client() [%s]:%d failed",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
return NULL;;
}
node->sock = new;
return new;
}

View File

@ -28,9 +28,10 @@
extern "C" {
#endif
ogs_sock_t *ogs_udp_socket(int family, ogs_socknode_t *node);
ogs_sock_t *ogs_udp_server(ogs_socknode_t *node, bool bindtodevice);
ogs_sock_t *ogs_udp_client(ogs_socknode_t *node);
ogs_sock_t *ogs_udp_server(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option);
ogs_sock_t *ogs_udp_client(
ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option);
int ogs_udp_connect(ogs_sock_t *sock, ogs_sockaddr_t *sa_list);
#ifdef __cplusplus

View File

@ -105,6 +105,9 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
const char *dev = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_sockopt_t option;
bool is_option = false;
if (ogs_yaml_iter_type(&gtpc_array) ==
YAML_MAPPING_NODE) {
memcpy(&gtpc_iter, &gtpc_array,
@ -161,6 +164,11 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
if (v) port = atoi(v);
} else if (!strcmp(gtpc_key, "dev")) {
dev = ogs_yaml_iter_value(&gtpc_iter);
} else if (!strcmp(gtpc_key, "option")) {
rv = ogs_app_config_parse_sockopt(
&gtpc_iter, &option);
if (rv != OGS_OK) return rv;
is_option = true;
} else
ogs_warn("unknown key `%s`", gtpc_key);
}
@ -175,10 +183,12 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
if (addr) {
if (ogs_app()->parameter.no_ipv4 == 0)
ogs_socknode_add(
&self.gtpc_list, AF_INET, addr);
&self.gtpc_list, AF_INET, addr,
is_option ? &option : NULL);
if (ogs_app()->parameter.no_ipv6 == 0)
ogs_socknode_add(
&self.gtpc_list6, AF_INET6, addr);
&self.gtpc_list6, AF_INET6, addr,
is_option ? &option : NULL);
ogs_freeaddrinfo(addr);
}
@ -188,7 +198,8 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
NULL : &self.gtpc_list,
ogs_app()->parameter.no_ipv6 ?
NULL : &self.gtpc_list6,
dev, port);
dev, port,
is_option ? &option : NULL);
ogs_assert(rv == OGS_OK);
}
@ -202,7 +213,7 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
NULL : &self.gtpc_list,
ogs_app()->parameter.no_ipv6 ?
NULL : &self.gtpc_list6,
NULL, self.gtpc_port);
NULL, self.gtpc_port, NULL);
ogs_assert(rv == OGS_OK);
}
} else if (!strcmp(local_key, "gtpu")) {
@ -229,6 +240,9 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
const char *network_instance = NULL;
const char *source_interface = NULL;
ogs_sockopt_t option;
bool is_option = false;
if (ogs_yaml_iter_type(&gtpu_array) ==
YAML_MAPPING_NODE) {
memcpy(&gtpu_iter, &gtpu_array,
@ -317,6 +331,11 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
if (v) port = atoi(v);
} else if (!strcmp(gtpu_key, "dev")) {
dev = ogs_yaml_iter_value(&gtpu_iter);
} else if (!strcmp(gtpu_key, "option")) {
rv = ogs_app_config_parse_sockopt(
&gtpu_iter, &option);
if (rv != OGS_OK) return rv;
is_option = true;
} else if (!strcmp(gtpu_key,
"teid_range_indication")) {
teid_range_indication =
@ -348,9 +367,13 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
if (addr) {
if (ogs_app()->parameter.no_ipv4 == 0)
ogs_socknode_add(&list, AF_INET, addr);
ogs_socknode_add(
&list, AF_INET, addr,
is_option ? &option : NULL);
if (ogs_app()->parameter.no_ipv6 == 0)
ogs_socknode_add(&list6, AF_INET6, addr);
ogs_socknode_add(
&list6, AF_INET6, addr,
is_option ? &option : NULL);
ogs_freeaddrinfo(addr);
}
@ -358,7 +381,8 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
rv = ogs_socknode_probe(
ogs_app()->parameter.no_ipv4 ? NULL : &list,
ogs_app()->parameter.no_ipv6 ? NULL : &list6,
dev, port);
dev, port,
is_option ? &option : NULL);
ogs_assert(rv == OGS_OK);
}
@ -452,9 +476,9 @@ int ogs_gtp_context_parse_config(const char *local, const char *remote)
ogs_list_init(&list6);
rv = ogs_socknode_probe(
ogs_app()->parameter.no_ipv4 ? NULL : &list,
ogs_app()->parameter.no_ipv6 ? NULL : &list6,
NULL, self.gtpu_port);
ogs_app()->parameter.no_ipv4 ? NULL : &list,
ogs_app()->parameter.no_ipv6 ? NULL : &list6,
NULL, self.gtpu_port, NULL);
ogs_assert(rv == OGS_OK);
/*
@ -544,8 +568,10 @@ ogs_gtp_node_t *ogs_gtp_node_add_by_f_teid(
ogs_app()->parameter.prefer_ipv4);
ogs_assert(addr);
#if 0 /* deprecated */
rv = ogs_socknode_fill_scope_id_in_local(addr);
ogs_assert(rv == OGS_OK);
#endif
node = ogs_gtp_node_new(addr);
ogs_assert(node);
@ -652,8 +678,10 @@ ogs_gtp_node_t *ogs_gtp_node_add_by_ip(
ogs_app()->parameter.prefer_ipv4);
ogs_expect_or_return_val(addr, NULL);
#if 0 /* deprecated */
rv = ogs_socknode_fill_scope_id_in_local(addr);
ogs_expect_or_return_val(rv == OGS_OK, NULL);
#endif
node = ogs_gtp_node_new(addr);
ogs_expect_or_return_val(node, NULL);

View File

@ -25,10 +25,12 @@ ogs_sock_t *ogs_gtp_server(ogs_socknode_t *node)
ogs_sock_t *gtp;
ogs_assert(node);
gtp = ogs_udp_server(node, ogs_app()->sockopt.bindtodevice);
gtp = ogs_udp_server(node->addr, node->option);
if (gtp) {
ogs_info("gtp_server() [%s]:%d",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
node->sock = gtp;
}
return gtp;

View File

@ -184,6 +184,9 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
const char *dev = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_sockopt_t option;
bool is_option = false;
if (ogs_yaml_iter_type(&pfcp_array) ==
YAML_MAPPING_NODE) {
memcpy(&pfcp_iter, &pfcp_array,
@ -244,6 +247,11 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
}
} else if (!strcmp(pfcp_key, "dev")) {
dev = ogs_yaml_iter_value(&pfcp_iter);
} else if (!strcmp(pfcp_key, "option")) {
rv = ogs_app_config_parse_sockopt(
&pfcp_iter, &option);
if (rv != OGS_OK) return rv;
is_option = true;
} else if (!strcmp(pfcp_key, "apn") ||
!strcmp(pfcp_key, "dnn")) {
/* Skip */
@ -261,10 +269,12 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
if (addr) {
if (ogs_app()->parameter.no_ipv4 == 0)
ogs_socknode_add(
&self.pfcp_list, AF_INET, addr);
&self.pfcp_list, AF_INET, addr,
is_option ? &option : NULL);
if (ogs_app()->parameter.no_ipv6 == 0)
ogs_socknode_add(
&self.pfcp_list6, AF_INET6, addr);
&self.pfcp_list6, AF_INET6, addr,
is_option ? &option : NULL);
ogs_freeaddrinfo(addr);
}
@ -274,7 +284,8 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
NULL : &self.pfcp_list,
ogs_app()->parameter.no_ipv6 ?
NULL : &self.pfcp_list6,
dev, self.pfcp_port);
dev, self.pfcp_port,
is_option ? &option : NULL);
ogs_assert(rv == OGS_OK);
}
@ -288,7 +299,7 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote)
NULL : &self.pfcp_list,
ogs_app()->parameter.no_ipv6 ?
NULL : &self.pfcp_list6,
NULL, self.pfcp_port);
NULL, self.pfcp_port, NULL);
ogs_assert(rv == OGS_OK);
}
} else if (!strcmp(local_key, "subnet")) {

View File

@ -25,10 +25,12 @@ ogs_sock_t *ogs_pfcp_server(ogs_socknode_t *node)
ogs_sock_t *pfcp;
ogs_assert(node);
pfcp = ogs_udp_server(node, ogs_app()->sockopt.bindtodevice);
pfcp = ogs_udp_server(node->addr, node->option);
if (pfcp) {
ogs_info("pfcp_server() [%s]:%d",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
node->sock = pfcp;
}
return pfcp;

View File

@ -158,6 +158,9 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
const char *dev = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_sockopt_t option;
bool is_option = false;
if (ogs_yaml_iter_type(&sbi_array) ==
YAML_MAPPING_NODE) {
memcpy(&sbi_iter, &sbi_array,
@ -238,6 +241,11 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
port = atoi(v);
} else if (!strcmp(sbi_key, "dev")) {
dev = ogs_yaml_iter_value(&sbi_iter);
} else if (!strcmp(sbi_key, "option")) {
rv = ogs_app_config_parse_sockopt(
&sbi_iter, &option);
if (rv != OGS_OK) return rv;
is_option = true;
} else if (!strcmp(sbi_key, "tls")) {
ogs_yaml_iter_t tls_iter;
ogs_yaml_iter_recurse(&sbi_iter, &tls_iter);
@ -270,9 +278,11 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
if (addr) {
if (ogs_app()->parameter.no_ipv4 == 0)
ogs_socknode_add(&list, AF_INET, addr);
ogs_socknode_add(
&list, AF_INET, addr, NULL);
if (ogs_app()->parameter.no_ipv6 == 0)
ogs_socknode_add(&list6, AF_INET6, addr);
ogs_socknode_add(
&list6, AF_INET6, addr, NULL);
ogs_freeaddrinfo(addr);
}
@ -280,7 +290,7 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
rv = ogs_socknode_probe(
ogs_app()->parameter.no_ipv4 ? NULL : &list,
ogs_app()->parameter.no_ipv6 ? NULL : &list6,
dev, port);
dev, port, NULL);
ogs_assert(rv == OGS_OK);
}
@ -293,8 +303,8 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
node = ogs_list_first(&list);
if (node) {
ogs_sbi_server_t *server =
ogs_sbi_server_add(node->addr);
ogs_sbi_server_t *server = ogs_sbi_server_add(
node->addr, is_option ? &option : NULL);
ogs_assert(server);
if (addr && ogs_app()->parameter.no_ipv4 == 0)
@ -306,8 +316,8 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
}
node6 = ogs_list_first(&list6);
if (node6) {
ogs_sbi_server_t *server =
ogs_sbi_server_add(node6->addr);
ogs_sbi_server_t *server = ogs_sbi_server_add(
node6->addr, is_option ? &option : NULL);
ogs_assert(server);
if (addr && ogs_app()->parameter.no_ipv6 == 0)
@ -334,13 +344,13 @@ int ogs_sbi_context_parse_config(const char *local, const char *remote)
rv = ogs_socknode_probe(
ogs_app()->parameter.no_ipv4 ? NULL : &list,
ogs_app()->parameter.no_ipv6 ? NULL : &list6,
NULL, self.sbi_port);
NULL, self.sbi_port, NULL);
ogs_assert(rv == OGS_OK);
node = ogs_list_first(&list);
if (node) ogs_sbi_server_add(node->addr);
if (node) ogs_sbi_server_add(node->addr, NULL);
node6 = ogs_list_first(&list6);
if (node6) ogs_sbi_server_add(node6->addr);
if (node6) ogs_sbi_server_add(node6->addr, NULL);
ogs_socknode_remove_all(&list);
ogs_socknode_remove_all(&list6);

View File

@ -123,12 +123,14 @@ static int server_start(ogs_sbi_server_t *server,
addr = server->node.addr;
ogs_assert(addr);
sock = ogs_tcp_server(&server->node);
sock = ogs_tcp_server(addr, server->node.option);
if (!sock) {
ogs_error("Cannot start SBI server");
return OGS_ERROR;
}
server->node.sock = sock;
/* Setup callback function */
server->cb = cb;

View File

@ -53,7 +53,8 @@ void ogs_sbi_server_final(void)
ogs_sbi_server_actions.cleanup();
}
ogs_sbi_server_t *ogs_sbi_server_add(ogs_sockaddr_t *addr)
ogs_sbi_server_t *ogs_sbi_server_add(
ogs_sockaddr_t *addr, ogs_sockopt_t *option)
{
ogs_sbi_server_t *server = NULL;
@ -64,6 +65,8 @@ ogs_sbi_server_t *ogs_sbi_server_add(ogs_sockaddr_t *addr)
memset(server, 0, sizeof(ogs_sbi_server_t));
ogs_assert(OGS_OK == ogs_copyaddrinfo(&server->node.addr, addr));
if (option)
server->node.option = ogs_memdup(option, sizeof *option);
ogs_list_add(&ogs_sbi_self()->server_list, server);
@ -78,6 +81,8 @@ void ogs_sbi_server_remove(ogs_sbi_server_t *server)
ogs_assert(server->node.addr);
ogs_freeaddrinfo(server->node.addr);
if (server->node.option)
ogs_free(server->node.option);
if (server->advertise)
ogs_freeaddrinfo(server->advertise);

View File

@ -62,7 +62,8 @@ typedef struct ogs_sbi_server_actions_s {
void ogs_sbi_server_init(int num_of_session_pool, int num_of_stream_pool);
void ogs_sbi_server_final(void);
ogs_sbi_server_t *ogs_sbi_server_add(ogs_sockaddr_t *addr);
ogs_sbi_server_t *ogs_sbi_server_add(
ogs_sockaddr_t *addr, ogs_sockopt_t *option);
void ogs_sbi_server_remove(ogs_sbi_server_t *server);
void ogs_sbi_server_remove_all(void);

View File

@ -23,10 +23,6 @@
#define OGS_LOG_DOMAIN __ogs_sock_domain
static int subscribe_to_events(ogs_sock_t *sock);
static int set_paddrparams(ogs_sock_t *sock);
static int set_rtoinfo(ogs_sock_t *sock);
static int set_initmsg(ogs_sock_t *sock);
static int set_nodelay(ogs_sock_t *sock, int on);
void ogs_sctp_init(uint16_t port)
{
@ -36,51 +32,68 @@ void ogs_sctp_final(void)
{
}
ogs_sock_t *ogs_sctp_socket(int family, int type, ogs_socknode_t *node)
ogs_sock_t *ogs_sctp_socket(int family, int type)
{
ogs_sock_t *new = NULL;
int rv;
new = ogs_sock_socket(family, type, IPPROTO_SCTP);
ogs_assert(new);
if (!new) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"ogs_sock_socket(faimly:%d type:%d) failed", family, type);
return NULL;
}
rv = subscribe_to_events(new);
ogs_assert(rv == OGS_OK);
rv = set_paddrparams(new);
ogs_assert(rv == OGS_OK);
rv = set_rtoinfo(new);
ogs_assert(rv == OGS_OK);
rv = set_initmsg(new);
ogs_assert(rv == OGS_OK);
if (ogs_app()->sockopt.no_delay == true) {
rv = set_nodelay(new, true);
ogs_assert(rv == OGS_OK);
} else {
ogs_warn("SCTP NO_DELAY Disabled");
if (rv != OGS_OK) {
ogs_sock_destroy(new);
return NULL;
}
return new;
}
ogs_sock_t *ogs_sctp_server(int type, ogs_socknode_t *node)
ogs_sock_t *ogs_sctp_server(
int type, ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
{
int rv;
ogs_sock_t *new;
ogs_sockaddr_t *addr;
char buf[OGS_ADDRSTRLEN];
ogs_assert(node);
ogs_assert(node->addr);
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
ogs_sockopt_t option;
addr = node->addr;
ogs_assert(sa_list);
ogs_sockopt_init(&option);
if (socket_option)
memcpy(&option, socket_option, sizeof option);
addr = sa_list;
while (addr) {
new = ogs_sctp_socket(addr->ogs_sa_family, type, node);
new = ogs_sctp_socket(addr->ogs_sa_family, type);
if (new) {
rv = ogs_listen_reusable(new->fd);
rv = ogs_sctp_peer_addr_params(new, &option);
ogs_assert(rv == OGS_OK);
rv = ogs_sctp_rto_info(new, &option);
ogs_assert(rv == OGS_OK);
rv = ogs_sctp_initmsg(new, &option);
ogs_assert(rv == OGS_OK);
if (option.sctp_nodelay == true) {
rv = ogs_sctp_nodelay(new, true);
ogs_assert(rv == OGS_OK);
} else
ogs_warn("SCTP NO_DELAY Disabled");
if (option.so_linger.l_onoff == true) {
rv = ogs_sctp_so_linger(new, option.so_linger.l_linger);
ogs_assert(rv == OGS_OK);
}
rv = ogs_listen_reusable(new->fd, true);
ogs_assert(rv == OGS_OK);
if (ogs_sock_bind(new, addr) == OGS_OK) {
@ -98,31 +111,58 @@ ogs_sock_t *ogs_sctp_server(int type, ogs_socknode_t *node)
if (addr == NULL) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"sctp_server() [%s]:%d failed",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
return NULL;
}
ogs_assert(new);
rv = ogs_sock_listen(new);
ogs_assert(rv == OGS_OK);
node->sock = new;
return new;
}
ogs_sock_t *ogs_sctp_client(int type, ogs_socknode_t *node)
ogs_sock_t *ogs_sctp_client(
int type, ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
{
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
int rv;
char buf[OGS_ADDRSTRLEN];
ogs_assert(node);
ogs_assert(node->addr);
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
ogs_sockopt_t option;
addr = node->addr;
ogs_assert(sa_list);
ogs_sockopt_init(&option);
if (socket_option)
memcpy(&option, socket_option, sizeof option);
addr = sa_list;
while (addr) {
new = ogs_sctp_socket(addr->ogs_sa_family, type, node);
new = ogs_sctp_socket(addr->ogs_sa_family, type);
if (new) {
rv = ogs_sctp_peer_addr_params(new, &option);
ogs_assert(rv == OGS_OK);
rv = ogs_sctp_rto_info(new, &option);
ogs_assert(rv == OGS_OK);
rv = ogs_sctp_initmsg(new, &option);
ogs_assert(rv == OGS_OK);
if (option.sctp_nodelay == true) {
rv = ogs_sctp_nodelay(new, true);
ogs_assert(rv == OGS_OK);
} else
ogs_warn("SCTP NO_DELAY Disabled");
if (option.so_linger.l_onoff == true) {
rv = ogs_sctp_so_linger(new, option.so_linger.l_linger);
ogs_assert(rv == OGS_OK);
}
if (ogs_sock_connect(new, addr) == OGS_OK) {
ogs_debug("sctp_client() [%s]:%d",
OGS_ADDR(addr, buf), OGS_PORT(addr));
@ -138,11 +178,11 @@ ogs_sock_t *ogs_sctp_client(int type, ogs_socknode_t *node)
if (addr == NULL) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"sctp_client() [%s]:%d failed",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
return NULL;
}
node->sock = new;
ogs_assert(new);
return new;
}
@ -452,12 +492,13 @@ static int sctp_setsockopt_paddrparams_workaround(
}
}
static int set_paddrparams(ogs_sock_t *sock)
int ogs_sctp_peer_addr_params(ogs_sock_t *sock, ogs_sockopt_t *option)
{
struct sctp_paddrparams paddrparams;
socklen_t socklen;
ogs_assert(sock);
ogs_assert(option);
memset(&paddrparams, 0, sizeof(paddrparams));
socklen = sizeof(paddrparams);
@ -481,9 +522,9 @@ static int set_paddrparams(ogs_sock_t *sock)
paddrparams.spp_pathmaxrxt);
#endif
paddrparams.spp_hbinterval = ogs_app()->sctp.heartbit_interval;
paddrparams.spp_hbinterval = option->sctp.spp_hbinterval;
#if !defined(__FreeBSD__)
paddrparams.spp_sackdelay = ogs_app()->sctp.sack_delay;
paddrparams.spp_sackdelay = option->sctp.spp_sackdelay;
#endif
#ifdef DISABLE_SCTP_EVENT_WORKAROUND
@ -516,12 +557,13 @@ static int set_paddrparams(ogs_sock_t *sock)
return OGS_OK;
}
static int set_rtoinfo(ogs_sock_t *sock)
int ogs_sctp_rto_info(ogs_sock_t *sock, ogs_sockopt_t *option)
{
struct sctp_rtoinfo rtoinfo;
socklen_t socklen;
ogs_assert(sock);
ogs_assert(option);
memset(&rtoinfo, 0, sizeof(rtoinfo));
socklen = sizeof(rtoinfo);
@ -537,9 +579,9 @@ static int set_rtoinfo(ogs_sock_t *sock)
rtoinfo.srto_max,
rtoinfo.srto_min);
rtoinfo.srto_initial = ogs_app()->sctp.rto_initial;
rtoinfo.srto_min = ogs_app()->sctp.rto_min;
rtoinfo.srto_max = ogs_app()->sctp.rto_max;
rtoinfo.srto_initial = option->sctp.srto_initial;
rtoinfo.srto_min = option->sctp.srto_min;
rtoinfo.srto_max = option->sctp.srto_max;
if (setsockopt(sock->fd, IPPROTO_SCTP, SCTP_RTOINFO,
&rtoinfo, sizeof(rtoinfo)) != 0) {
@ -547,6 +589,7 @@ static int set_rtoinfo(ogs_sock_t *sock)
"setsockopt for SCTP_RTOINFO failed");
return OGS_ERROR;
}
ogs_debug("New RTO (initial:%d max:%d min:%d)",
rtoinfo.srto_initial,
rtoinfo.srto_max,
@ -555,13 +598,14 @@ static int set_rtoinfo(ogs_sock_t *sock)
return OGS_OK;
}
static int set_initmsg(ogs_sock_t *sock)
int ogs_sctp_initmsg(ogs_sock_t *sock, ogs_sockopt_t *option)
{
struct sctp_initmsg initmsg;
socklen_t socklen;
ogs_assert(sock);
ogs_assert(ogs_app()->sctp.max_num_of_ostreams > 1);
ogs_assert(option);
ogs_assert(option->sctp.sinit_num_ostreams > 1);
memset(&initmsg, 0, sizeof(initmsg));
socklen = sizeof(initmsg);
@ -578,10 +622,10 @@ static int set_initmsg(ogs_sock_t *sock)
initmsg.sinit_max_attempts,
initmsg.sinit_max_init_timeo);
initmsg.sinit_num_ostreams = ogs_app()->sctp.max_num_of_ostreams;
initmsg.sinit_max_instreams = ogs_app()->sctp.max_num_of_istreams;
initmsg.sinit_max_attempts = ogs_app()->sctp.max_attempts;
initmsg.sinit_max_init_timeo = ogs_app()->sctp.max_initial_timeout;
initmsg.sinit_num_ostreams = option->sctp.sinit_num_ostreams;
initmsg.sinit_max_instreams = option->sctp.sinit_max_instreams;
initmsg.sinit_max_attempts = option->sctp.sinit_max_attempts;
initmsg.sinit_max_init_timeo = option->sctp.sinit_max_init_timeo;
if (setsockopt(sock->fd, IPPROTO_SCTP, SCTP_INITMSG,
&initmsg, sizeof(initmsg)) != 0) {
@ -599,7 +643,7 @@ static int set_initmsg(ogs_sock_t *sock)
return OGS_OK;
}
static int set_nodelay(ogs_sock_t *sock, int on)
int ogs_sctp_nodelay(ogs_sock_t *sock, int on)
{
ogs_assert(sock);
@ -607,9 +651,15 @@ static int set_nodelay(ogs_sock_t *sock, int on)
if (setsockopt(sock->fd, IPPROTO_SCTP, SCTP_NODELAY,
&on, sizeof(on)) != 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"setsockopt for SCTP_NODELAY failed");
"setsockopt(IPPROTO_SCTP, SCTP_NODELAY) failed");
return OGS_ERROR;
}
return OGS_OK;
}
int ogs_sctp_so_linger(ogs_sock_t *sock, int l_linger)
{
ogs_assert(sock);
return ogs_so_linger(sock->fd, l_linger);
}

View File

@ -104,15 +104,23 @@ typedef struct ogs_sctp_info_s {
void ogs_sctp_init(uint16_t port);
void ogs_sctp_final(void);
ogs_sock_t *ogs_sctp_socket(int family, int type, ogs_socknode_t *node);
ogs_sock_t *ogs_sctp_socket(int family, int type);
ogs_sock_t *ogs_sctp_server(int type, ogs_socknode_t *node);
ogs_sock_t *ogs_sctp_client(int type, ogs_socknode_t *node);
ogs_sock_t *ogs_sctp_server(
int type, ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option);
ogs_sock_t *ogs_sctp_client(
int type, ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option);
int ogs_sctp_bind(ogs_sock_t *sock, ogs_sockaddr_t *sa_list);
int ogs_sctp_connect(ogs_sock_t *sock, ogs_sockaddr_t *sa_list);
int ogs_sctp_listen(ogs_sock_t *sock);
int ogs_sctp_peer_addr_params(ogs_sock_t *sock, ogs_sockopt_t *option);
int ogs_sctp_rto_info(ogs_sock_t *sock, ogs_sockopt_t *option);
int ogs_sctp_initmsg(ogs_sock_t *sock, ogs_sockopt_t *option);
int ogs_sctp_nodelay(ogs_sock_t *sock, int on);
int ogs_sctp_so_linger(ogs_sock_t *sock, int l_linger);
int ogs_sctp_sendmsg(ogs_sock_t *sock, const void *msg, size_t len,
ogs_sockaddr_t *to, uint32_t ppid, uint16_t stream_no);
int ogs_sctp_recvmsg(ogs_sock_t *sock, void *msg, size_t len,

View File

@ -41,10 +41,9 @@ void ogs_sctp_final()
}
}
ogs_sock_t *ogs_sctp_socket(int family, int type, ogs_socknode_t *node)
ogs_sock_t *ogs_sctp_socket(int family, int type)
{
struct socket *socket = NULL;
struct linger l;
const int on = 1;
struct sctp_event event;
uint16_t event_types[] = {
@ -55,8 +54,6 @@ ogs_sock_t *ogs_sctp_socket(int family, int type, ogs_socknode_t *node)
SCTP_ADAPTATION_INDICATION,
SCTP_PARTIAL_DELIVERY_EVENT
};
struct sctp_initmsg initmsg;
socklen_t socklen;
int i;
if (!(socket = usrsctp_socket(family, type, IPPROTO_SCTP,
@ -65,27 +62,6 @@ ogs_sock_t *ogs_sctp_socket(int family, int type, ogs_socknode_t *node)
return NULL;
}
if (ogs_app()->sockopt.no_delay == true) {
if (usrsctp_setsockopt(socket, IPPROTO_SCTP, SCTP_NODELAY,
&on, sizeof(int)) < 0) {
ogs_error("usrsctp_setsockopt SCTP_NODELAY failed");
return NULL;
}
} else {
ogs_warn("SCTP NO_DELAY Disabled");
}
if (ogs_app()->sockopt.l_onoff == true) {
memset(&l, 0, sizeof(l));
l.l_onoff = 1;
l.l_linger = ogs_app()->sockopt.l_linger;
if (usrsctp_setsockopt(socket, SOL_SOCKET, SO_LINGER,
(const void *)&l, (socklen_t) sizeof(struct linger)) < 0) {
ogs_error("Could not set SO_LINGER on SCTP socket");
return NULL;
}
}
if (usrsctp_setsockopt(socket, IPPROTO_SCTP, SCTP_RECVRCVINFO,
&on, sizeof(int)) < 0) {
ogs_error("usrsctp_setsockopt SCTP_RECVRCVINFO failed");
@ -104,42 +80,7 @@ ogs_sock_t *ogs_sctp_socket(int family, int type, ogs_socknode_t *node)
}
}
memset(&initmsg, 0, sizeof(struct sctp_initmsg));
socklen = sizeof(struct sctp_initmsg);
if (usrsctp_getsockopt(socket, IPPROTO_SCTP, SCTP_INITMSG,
&initmsg, &socklen) != 0) {
ogs_error("getsockopt for SCTP_INITMSG failed(%d:%s)",
errno, strerror( errno ));
return NULL;
}
ogs_debug("Old INITMSG (numout:%d maxin:%d maxattempt:%d maxinit_to:%d)",
initmsg.sinit_num_ostreams,
initmsg.sinit_max_instreams,
initmsg.sinit_max_attempts,
initmsg.sinit_max_init_timeo);
ogs_assert(ogs_app()->sctp.max_num_of_ostreams > 1);
initmsg.sinit_num_ostreams = ogs_app()->sctp.max_num_of_ostreams;
initmsg.sinit_max_instreams = ogs_app()->sctp.max_num_of_istreams;
initmsg.sinit_max_attempts = ogs_app()->sctp.max_attempts;
initmsg.sinit_max_init_timeo = ogs_app()->sctp.max_initial_timeout;
if (usrsctp_setsockopt(socket, IPPROTO_SCTP, SCTP_INITMSG,
&initmsg, sizeof(initmsg)) != 0) {
ogs_error("setsockopt for SCTP_INITMSG failed(%d:%s)",
errno, strerror( errno ));
return NULL;
}
ogs_debug("New INITMSG (numout:%d maxin:%d maxattempt:%d maxinit_to:%d)",
initmsg.sinit_num_ostreams,
initmsg.sinit_max_instreams,
initmsg.sinit_max_attempts,
initmsg.sinit_max_init_timeo);
return (ogs_sock_t *)socket;;
return (ogs_sock_t *)socket;
}
void ogs_sctp_destroy(ogs_sock_t *sock)
@ -148,27 +89,53 @@ void ogs_sctp_destroy(ogs_sock_t *sock)
usrsctp_close((struct socket *)sock);
}
ogs_sock_t *ogs_sctp_server(int type, ogs_socknode_t *node)
ogs_sock_t *ogs_sctp_server(
int type, ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
{
int rv;
char buf[OGS_ADDRSTRLEN];
ogs_sock_t *sock = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_assert(node);
ogs_assert(node->addr);
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
ogs_sockopt_t option;
addr = node->addr;
ogs_assert(sa_list);
ogs_sockopt_init(&option);
if (socket_option)
memcpy(&option, socket_option, sizeof option);
addr = sa_list;
while (addr) {
sock = ogs_sctp_socket(addr->ogs_sa_family, type, node);
if (sock) {
if (ogs_sctp_bind(sock, addr) == OGS_OK) {
new = ogs_sctp_socket(addr->ogs_sa_family, type);
if (new) {
rv = ogs_sctp_peer_addr_params(new, &option);
ogs_assert(rv == OGS_OK);
rv = ogs_sctp_rto_info(new, &option);
ogs_assert(rv == OGS_OK);
rv = ogs_sctp_initmsg(new, &option);
ogs_assert(rv == OGS_OK);
if (option.sctp_nodelay == true) {
rv = ogs_sctp_nodelay(new, true);
ogs_assert(rv == OGS_OK);
} else
ogs_warn("SCTP NO_DELAY Disabled");
if (option.so_linger.l_onoff == true) {
rv = ogs_sctp_so_linger(new, option.so_linger.l_linger);
ogs_assert(rv == OGS_OK);
}
if (ogs_sctp_bind(new, addr) == OGS_OK) {
ogs_trace("sctp_server [%s]:%d",
OGS_ADDR(addr, buf), OGS_PORT(addr));
break;
}
ogs_sctp_destroy(sock);
ogs_sctp_destroy(new);
}
addr = addr->next;
@ -176,39 +143,65 @@ ogs_sock_t *ogs_sctp_server(int type, ogs_socknode_t *node)
if (addr == NULL) {
ogs_error("sctp_server [%s]:%d failed",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
return NULL;
}
rv = ogs_sctp_listen(sock);
ogs_assert(new);
rv = ogs_sctp_listen(new);
ogs_assert(rv == OGS_OK);
node->sock = sock;
node->cleanup = ogs_sctp_destroy;
return sock;
return new;
}
ogs_sock_t *ogs_sctp_client(int type, ogs_socknode_t *node)
ogs_sock_t *ogs_sctp_client(
int type, ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option)
{
ogs_sock_t *sock = NULL;
ogs_sockaddr_t *addr = NULL;
int rv;
char buf[OGS_ADDRSTRLEN];
ogs_assert(node);
ogs_assert(node->addr);
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
ogs_sockopt_t option;
addr = node->addr;
ogs_assert(sa_list);
ogs_sockopt_init(&option);
if (socket_option)
memcpy(&option, socket_option, sizeof option);
addr = sa_list;
while (addr) {
sock = ogs_sctp_socket(addr->ogs_sa_family, type, node);
if (sock) {
if (ogs_sctp_connect(sock, addr) == OGS_OK) {
new = ogs_sctp_socket(addr->ogs_sa_family, type);
if (new) {
rv = ogs_sctp_peer_addr_params(new, &option);
ogs_assert(rv == OGS_OK);
rv = ogs_sctp_rto_info(new, &option);
ogs_assert(rv == OGS_OK);
rv = ogs_sctp_initmsg(new, &option);
ogs_assert(rv == OGS_OK);
if (option.sctp_nodelay == true) {
rv = ogs_sctp_nodelay(new, true);
ogs_assert(rv == OGS_OK);
} else
ogs_warn("SCTP NO_DELAY Disabled");
if (option.so_linger.l_onoff == true) {
rv = ogs_sctp_so_linger(new, option.so_linger.l_linger);
ogs_assert(rv == OGS_OK);
}
if (ogs_sctp_connect(new, addr) == OGS_OK) {
ogs_trace("sctp_client [%s]:%d",
OGS_ADDR(addr, buf), OGS_PORT(addr));
break;
}
ogs_sctp_destroy(sock);
ogs_sctp_destroy(new);
}
addr = addr->next;
@ -216,17 +209,13 @@ ogs_sock_t *ogs_sctp_client(int type, ogs_socknode_t *node)
if (addr == NULL) {
ogs_error("sctp_client [%s]:%d failed",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
OGS_ADDR(sa_list, buf), OGS_PORT(sa_list));
return NULL;
}
node->sock = sock;
node->cleanup = ogs_sctp_destroy;
return sock;
return new;
}
int ogs_sctp_bind(ogs_sock_t *sock, ogs_sockaddr_t *sa_list)
{
struct socket *socket = (struct socket *)sock;
@ -407,3 +396,169 @@ static void ogs_debug_printf(const char *format, ...)
va_end(ap);
}
int ogs_sctp_peer_addr_params(ogs_sock_t *sock, ogs_sockopt_t *option)
{
struct socket *socket = (struct socket *)sock;
struct sctp_paddrparams paddrparams;
socklen_t socklen;
ogs_assert(socket);
ogs_assert(option);
memset(&paddrparams, 0, sizeof(paddrparams));
socklen = sizeof(paddrparams);
if (usrsctp_getsockopt(socket, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
&paddrparams, &socklen) != 0) {
ogs_error("getsockopt for SCTP_PEER_ADDR failed(%d:%s)",
errno, strerror( errno ));
return OGS_ERROR;
}
ogs_debug("OLD spp_flags = 0x%x hbinter = %d pathmax = %d",
paddrparams.spp_flags,
paddrparams.spp_hbinterval,
paddrparams.spp_pathmaxrxt);
paddrparams.spp_hbinterval = option->sctp.spp_hbinterval;
if (usrsctp_setsockopt(socket, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
&paddrparams, sizeof(paddrparams)) != 0) {
ogs_error("setsockopt for SCTP_PEER_ADDR_PARAMS failed(%d:%s)",
errno, strerror( errno ));
return OGS_ERROR;
}
ogs_debug("NEW spp_flags = 0x%x hbinter = %d pathmax = %d",
paddrparams.spp_flags,
paddrparams.spp_hbinterval,
paddrparams.spp_pathmaxrxt);
return OGS_OK;
}
int ogs_sctp_rto_info(ogs_sock_t *sock, ogs_sockopt_t *option)
{
struct socket *socket = (struct socket *)sock;
struct sctp_rtoinfo rtoinfo;
socklen_t socklen;
ogs_assert(sock);
ogs_assert(option);
memset(&rtoinfo, 0, sizeof(rtoinfo));
socklen = sizeof(rtoinfo);
if (usrsctp_getsockopt(socket, IPPROTO_SCTP, SCTP_RTOINFO,
&rtoinfo, &socklen) != 0) {
ogs_error("getsockopt for SCTP_RTOINFO failed(%d:%s)",
errno, strerror( errno ));
return OGS_ERROR;
}
ogs_debug("OLD RTO (initial:%d max:%d min:%d)",
rtoinfo.srto_initial,
rtoinfo.srto_max,
rtoinfo.srto_min);
rtoinfo.srto_initial = option->sctp.srto_initial;
rtoinfo.srto_min = option->sctp.srto_min;
rtoinfo.srto_max = option->sctp.srto_max;
if (usrsctp_setsockopt(socket, IPPROTO_SCTP, SCTP_RTOINFO,
&rtoinfo, sizeof(rtoinfo)) != 0) {
ogs_error("setsockopt for SCTP_RTOINFO failed(%d:%s)",
errno, strerror( errno ));
return OGS_ERROR;
}
ogs_debug("New RTO (initial:%d max:%d min:%d)",
rtoinfo.srto_initial,
rtoinfo.srto_max,
rtoinfo.srto_min);
return OGS_OK;
}
int ogs_sctp_initmsg(ogs_sock_t *sock, ogs_sockopt_t *option)
{
struct socket *socket = (struct socket *)sock;
struct sctp_initmsg initmsg;
socklen_t socklen;
ogs_assert(socket);
ogs_assert(option);
ogs_assert(option->sctp.sinit_num_ostreams > 1);
memset(&initmsg, 0, sizeof(struct sctp_initmsg));
socklen = sizeof(struct sctp_initmsg);
if (usrsctp_getsockopt(socket, IPPROTO_SCTP, SCTP_INITMSG,
&initmsg, &socklen) != 0) {
ogs_error("getsockopt for SCTP_INITMSG failed(%d:%s)",
errno, strerror( errno ));
return OGS_ERROR;
}
ogs_debug("Old INITMSG (numout:%d maxin:%d maxattempt:%d maxinit_to:%d)",
initmsg.sinit_num_ostreams,
initmsg.sinit_max_instreams,
initmsg.sinit_max_attempts,
initmsg.sinit_max_init_timeo);
initmsg.sinit_num_ostreams = option->sctp.sinit_num_ostreams;
initmsg.sinit_max_instreams = option->sctp.sinit_max_instreams;
initmsg.sinit_max_attempts = option->sctp.sinit_max_attempts;
initmsg.sinit_max_init_timeo = option->sctp.sinit_max_init_timeo;
if (usrsctp_setsockopt(socket, IPPROTO_SCTP, SCTP_INITMSG,
&initmsg, sizeof(initmsg)) != 0) {
ogs_error("setsockopt for SCTP_INITMSG failed(%d:%s)",
errno, strerror( errno ));
return OGS_ERROR;
}
ogs_debug("New INITMSG (numout:%d maxin:%d maxattempt:%d maxinit_to:%d)",
initmsg.sinit_num_ostreams,
initmsg.sinit_max_instreams,
initmsg.sinit_max_attempts,
initmsg.sinit_max_init_timeo);
return OGS_OK;
}
int ogs_sctp_nodelay(ogs_sock_t *sock, int on)
{
struct socket *socket = (struct socket *)sock;
ogs_assert(socket);
ogs_debug("Turn on SCTP_NODELAY");
if (usrsctp_setsockopt(socket, IPPROTO_SCTP, SCTP_NODELAY,
&on, sizeof(int)) < 0) {
ogs_error("usrsctp_setsockopt(IPPROTO_SCTP, SCTP_NODELAY) failed");
return OGS_ERROR;
}
return OGS_OK;
}
int ogs_sctp_so_linger(ogs_sock_t *sock, int l_linger)
{
struct socket *socket = (struct socket *)sock;
struct linger l;
ogs_assert(socket);
ogs_assert(l_linger);
memset(&l, 0, sizeof(l));
l.l_onoff = 1;
l.l_linger = l_linger;
if (usrsctp_setsockopt(socket, SOL_SOCKET, SO_LINGER,
(const void *)&l, (socklen_t) sizeof(struct linger)) < 0) {
ogs_error("Could not set SO_LINGER on SCTP socket");
return OGS_ERROR;
}
return OGS_OK;
}

View File

@ -649,10 +649,13 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_free(addr);
}
gnb->max_num_of_ostreams =
ogs_min(max_num_of_ostreams, gnb->max_num_of_ostreams);
if (gnb->max_num_of_ostreams)
gnb->max_num_of_ostreams =
ogs_min(max_num_of_ostreams, gnb->max_num_of_ostreams);
else
gnb->max_num_of_ostreams = max_num_of_ostreams;
ogs_debug("gNB-N2 SCTP_COMM_UP[%s] Max Num of Outbound Streams[%d]",
ogs_info("gNB-N2[%s] max_num_of_ostreams : %d",
OGS_ADDR(gnb->sctp.addr, buf), gnb->max_num_of_ostreams);
break;

View File

@ -213,6 +213,9 @@ int amf_context_parse_config(void)
const char *dev = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_sockopt_t option;
bool is_option = false;
if (ogs_yaml_iter_type(&ngap_array) ==
YAML_MAPPING_NODE) {
memcpy(&ngap_iter, &ngap_array,
@ -269,6 +272,11 @@ int amf_context_parse_config(void)
if (v) port = atoi(v);
} else if (!strcmp(ngap_key, "dev")) {
dev = ogs_yaml_iter_value(&ngap_iter);
} else if (!strcmp(ngap_key, "option")) {
rv = ogs_app_config_parse_sockopt(
&ngap_iter, &option);
if (rv != OGS_OK) return rv;
is_option = true;
} else
ogs_warn("unknown key `%s`", ngap_key);
}
@ -283,10 +291,12 @@ int amf_context_parse_config(void)
if (addr) {
if (ogs_app()->parameter.no_ipv4 == 0)
ogs_socknode_add(
&self.ngap_list, AF_INET, addr);
&self.ngap_list, AF_INET, addr,
is_option ? &option : NULL);
if (ogs_app()->parameter.no_ipv6 == 0)
ogs_socknode_add(
&self.ngap_list6, AF_INET6, addr);
&self.ngap_list6, AF_INET6, addr,
is_option ? &option : NULL);
ogs_freeaddrinfo(addr);
}
@ -296,7 +306,8 @@ int amf_context_parse_config(void)
NULL : &self.ngap_list,
ogs_app()->parameter.no_ipv6 ?
NULL : &self.ngap_list6,
dev, port);
dev, port,
is_option ? &option : NULL);
ogs_assert(rv == OGS_OK);
}
@ -310,7 +321,7 @@ int amf_context_parse_config(void)
NULL : &self.ngap_list,
ogs_app()->parameter.no_ipv6 ?
NULL : &self.ngap_list6,
NULL, self.ngap_port);
NULL, self.ngap_port, NULL);
ogs_assert(rv == OGS_OK);
}
} else if (!strcmp(amf_key, "guami")) {
@ -847,12 +858,8 @@ amf_gnb_t *amf_gnb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr)
ogs_assert(gnb->sctp.poll.read);
}
gnb->max_num_of_ostreams = OGS_DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS;
gnb->max_num_of_ostreams = 0;
gnb->ostream_id = 0;
if (ogs_app()->sctp.max_num_of_ostreams) {
gnb->max_num_of_ostreams = ogs_app()->sctp.max_num_of_ostreams;
ogs_info("[GNB] max_num_of_ostreams : %d", gnb->max_num_of_ostreams);
}
ogs_list_init(&gnb->ran_ue_list);
@ -970,6 +977,7 @@ ran_ue_t *ran_ue_add(amf_gnb_t *gnb, uint32_t ran_ue_ngap_id)
* 0 : Non UE signalling
* 1-29 : UE specific association
*/
ogs_assert((gnb->max_num_of_ostreams-1) >= 1); /* NEXT_ID(MAX >= MIN) */
ran_ue->gnb_ostream_id =
OGS_NEXT_ID(gnb->ostream_id, 1, gnb->max_num_of_ostreams-1);

View File

@ -34,22 +34,30 @@ ogs_sock_t *ngap_server(ogs_socknode_t *node)
{
char buf[OGS_ADDRSTRLEN];
ogs_sock_t *sock = NULL;
#if !HAVE_USRSCTP
ogs_poll_t *poll = NULL;
#endif
ogs_assert(node);
#if HAVE_USRSCTP
sock = ogs_sctp_server(SOCK_SEQPACKET, node);
sock = ogs_sctp_server(SOCK_SEQPACKET, node->addr, node->option);
if (!sock) return NULL;
usrsctp_set_non_blocking((struct socket *)sock, 1);
usrsctp_set_upcall((struct socket *)sock, usrsctp_recv_handler, NULL);
#else
sock = ogs_sctp_server(SOCK_STREAM, node);
sock = ogs_sctp_server(SOCK_STREAM, node->addr, node->option);
if (!sock) return NULL;
node->poll = ogs_pollset_add(ogs_app()->pollset,
poll = ogs_pollset_add(ogs_app()->pollset,
OGS_POLLIN, sock->fd, lksctp_accept_handler, sock);
ogs_assert(node->poll);
ogs_assert(node);
node->poll = poll;
#endif
node->sock = sock;
node->cleanup = ogs_sctp_destroy;
ogs_info("ngap_server() [%s]:%d",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));

View File

@ -423,6 +423,9 @@ int mme_context_parse_config()
const char *dev = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_sockopt_t option;
bool is_option = false;
if (ogs_yaml_iter_type(&s1ap_array) ==
YAML_MAPPING_NODE) {
memcpy(&s1ap_iter, &s1ap_array,
@ -479,6 +482,11 @@ int mme_context_parse_config()
if (v) port = atoi(v);
} else if (!strcmp(s1ap_key, "dev")) {
dev = ogs_yaml_iter_value(&s1ap_iter);
} else if (!strcmp(s1ap_key, "option")) {
rv = ogs_app_config_parse_sockopt(
&s1ap_iter, &option);
if (rv != OGS_OK) return rv;
is_option = true;
} else
ogs_warn("unknown key `%s`", s1ap_key);
}
@ -493,10 +501,12 @@ int mme_context_parse_config()
if (addr) {
if (ogs_app()->parameter.no_ipv4 == 0)
ogs_socknode_add(
&self.s1ap_list, AF_INET, addr);
&self.s1ap_list, AF_INET, addr,
is_option ? &option : NULL);
if (ogs_app()->parameter.no_ipv6 == 0)
ogs_socknode_add(
&self.s1ap_list6, AF_INET6, addr);
&self.s1ap_list6, AF_INET6, addr,
is_option ? &option : NULL);
ogs_freeaddrinfo(addr);
}
@ -506,7 +516,8 @@ int mme_context_parse_config()
NULL : &self.s1ap_list,
ogs_app()->parameter.no_ipv6 ?
NULL : &self.s1ap_list6,
dev, port);
dev, port,
is_option ? &option : NULL);
ogs_assert(rv == OGS_OK);
}
@ -520,7 +531,7 @@ int mme_context_parse_config()
NULL : &self.s1ap_list,
ogs_app()->parameter.no_ipv6 ?
NULL : &self.s1ap_list6,
NULL, self.s1ap_port);
NULL, self.s1ap_port, NULL);
ogs_assert(rv == OGS_OK);
}
} else if (!strcmp(mme_key, "gtpc")) {
@ -965,6 +976,9 @@ int mme_context_parse_config()
const char *hostname[OGS_MAX_NUM_OF_HOSTNAME];
uint16_t port = self.sgsap_port;
ogs_sockopt_t option;
bool is_option = false;
if (ogs_yaml_iter_type(&sgsap_array) ==
YAML_MAPPING_NODE) {
memcpy(&sgsap_iter, &sgsap_array,
@ -1025,6 +1039,11 @@ int mme_context_parse_config()
port = atoi(v);
self.sgsap_port = port;
}
} else if (!strcmp(sgsap_key, "option")) {
rv = ogs_app_config_parse_sockopt(
&sgsap_iter, &option);
if (rv != OGS_OK) return rv;
is_option = true;
} else if (!strcmp(sgsap_key, "map")) {
ogs_yaml_iter_t map_iter;
ogs_yaml_iter_recurse(&sgsap_iter, &map_iter);
@ -1227,7 +1246,7 @@ int mme_context_parse_config()
if (addr == NULL) continue;
vlr = mme_vlr_add(addr);
vlr = mme_vlr_add(addr, is_option ? &option : NULL);
ogs_assert(vlr);
for (i = 0; i < map_num; i++) {
@ -1632,7 +1651,7 @@ ogs_sockaddr_t *mme_pgw_addr_find_by_apn(
return NULL;
}
mme_vlr_t *mme_vlr_add(ogs_sockaddr_t *sa_list)
mme_vlr_t *mme_vlr_add(ogs_sockaddr_t *sa_list, ogs_sockopt_t *option)
{
mme_vlr_t *vlr = NULL;
@ -1646,6 +1665,10 @@ mme_vlr_t *mme_vlr_add(ogs_sockaddr_t *sa_list)
vlr->ostream_id = 0;
vlr->sa_list = sa_list;
if (option) {
vlr->max_num_of_ostreams = option->sctp.sinit_num_ostreams;
vlr->option = ogs_memdup(option, sizeof *option);
}
ogs_list_add(&self.vlr_list, vlr);
@ -1661,6 +1684,8 @@ void mme_vlr_remove(mme_vlr_t *vlr)
mme_vlr_close(vlr);
ogs_freeaddrinfo(vlr->sa_list);
if (vlr->option)
ogs_free(vlr->option);
ogs_pool_free(&mme_vlr_pool, vlr);
}
@ -1783,12 +1808,8 @@ mme_enb_t *mme_enb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr)
ogs_list_init(&enb->sctp.write_queue);
}
enb->max_num_of_ostreams = OGS_DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS;
enb->max_num_of_ostreams = 0;
enb->ostream_id = 0;
if (ogs_app()->sctp.max_num_of_ostreams) {
enb->max_num_of_ostreams = ogs_app()->sctp.max_num_of_ostreams;
ogs_info("[ENB] max_num_of_ostreams : %d", enb->max_num_of_ostreams);
}
ogs_list_init(&enb->enb_ue_list);
@ -1917,6 +1938,7 @@ enb_ue_t *enb_ue_add(mme_enb_t *enb, uint32_t enb_ue_s1ap_id)
* 0 : Non UE signalling
* 1-29 : UE specific association
*/
ogs_assert((enb->max_num_of_ostreams-1) >= 1); /* NEXT_ID(MAX >= MIN) */
enb_ue->enb_ostream_id =
OGS_NEXT_ID(enb->ostream_id, 1, enb->max_num_of_ostreams-1);

View File

@ -184,6 +184,7 @@ typedef struct mme_vlr_s {
ogs_sock_t *sock; /* VLR SGsAP Socket */
ogs_sockaddr_t *addr; /* VLR SGsAP Connected Socket Address */
ogs_sockopt_t *option; /* VLR SGsAP Socket Option */
ogs_poll_t *poll; /* VLR SGsAP Poll */
} mme_vlr_t;
@ -670,7 +671,7 @@ void mme_pgw_remove_all(void);
ogs_sockaddr_t *mme_pgw_addr_find_by_apn(
ogs_list_t *list, int family, char *apn);
mme_vlr_t *mme_vlr_add(ogs_sockaddr_t *addr);
mme_vlr_t *mme_vlr_add(ogs_sockaddr_t *addr, ogs_sockopt_t *option);
void mme_vlr_remove(mme_vlr_t *vlr);
void mme_vlr_remove_all(void);
void mme_vlr_close(mme_vlr_t *vlr);

View File

@ -184,10 +184,13 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
ogs_free(addr);
}
enb->max_num_of_ostreams =
ogs_min(max_num_of_ostreams, enb->max_num_of_ostreams);
if (enb->max_num_of_ostreams)
enb->max_num_of_ostreams =
ogs_min(max_num_of_ostreams, enb->max_num_of_ostreams);
else
enb->max_num_of_ostreams = max_num_of_ostreams;
ogs_debug("eNB-S1 SCTP_COMM_UP[%s] Max Num of Outbound Streams[%d]",
ogs_info("eNB-N2[%s] max_num_of_ostreams : %d",
OGS_ADDR(enb->sctp.addr, buf), enb->max_num_of_ostreams);
break;

View File

@ -35,22 +35,30 @@ ogs_sock_t *s1ap_server(ogs_socknode_t *node)
{
char buf[OGS_ADDRSTRLEN];
ogs_sock_t *sock = NULL;
#if !HAVE_USRSCTP
ogs_poll_t *poll = NULL;
#endif
ogs_assert(node);
#if HAVE_USRSCTP
sock = ogs_sctp_server(SOCK_SEQPACKET, node);
sock = ogs_sctp_server(SOCK_SEQPACKET, node->addr, node->option);
if (!sock) return NULL;
usrsctp_set_non_blocking((struct socket *)sock, 1);
usrsctp_set_upcall((struct socket *)sock, usrsctp_recv_handler, NULL);
#else
sock = ogs_sctp_server(SOCK_STREAM, node);
sock = ogs_sctp_server(SOCK_STREAM, node->addr, node->option);
if (!sock) return NULL;
node->poll = ogs_pollset_add(ogs_app()->pollset,
poll = ogs_pollset_add(ogs_app()->pollset,
OGS_POLLIN, sock->fd, lksctp_accept_handler, sock);
ogs_assert(node->poll);
ogs_assert(poll);
node->poll = poll;
#endif
node->sock = sock;
node->cleanup = ogs_sctp_destroy;
ogs_info("s1ap_server() [%s]:%d",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));

View File

@ -35,19 +35,15 @@ static void recv_handler(ogs_sock_t *sock);
ogs_sock_t *sgsap_client(mme_vlr_t *vlr)
{
char buf[OGS_ADDRSTRLEN];
ogs_socknode_t node;
ogs_sock_t *sock = NULL;
ogs_assert(vlr);
memset(&node, 0, sizeof node);
node.addr = vlr->sa_list;
sock = ogs_sctp_client(SOCK_SEQPACKET, &node);
sock = ogs_sctp_client(SOCK_SEQPACKET, vlr->sa_list, vlr->option);
if (sock) {
vlr->sock = sock;
#if HAVE_USRSCTP
vlr->addr = node.addr;
vlr->addr = vlr->sa_list;
usrsctp_set_non_blocking((struct socket *)sock, 1);
usrsctp_set_upcall((struct socket *)sock, usrsctp_recv_handler, NULL);
#else

View File

@ -114,6 +114,9 @@ int nssf_context_parse_config(void)
const char *key = NULL, *pem = NULL;
const char *sst = NULL, *sd = NULL;
ogs_sockopt_t option;
bool is_option = false;
if (ogs_yaml_iter_type(&nsi_array) ==
YAML_MAPPING_NODE) {
memcpy(&nsi_iter, &nsi_array,
@ -173,6 +176,11 @@ int nssf_context_parse_config(void)
}
} else if (!strcmp(nsi_key, "dev")) {
dev = ogs_yaml_iter_value(&nsi_iter);
} else if (!strcmp(nsi_key, "option")) {
rv = ogs_app_config_parse_sockopt(
&nsi_iter, &option);
if (rv != OGS_OK) return rv;
is_option = true;
} else if (!strcmp(nsi_key, "tls")) {
ogs_yaml_iter_t tls_iter;
ogs_yaml_iter_recurse(&nsi_iter, &tls_iter);
@ -223,9 +231,13 @@ int nssf_context_parse_config(void)
if (addr) {
if (ogs_app()->parameter.no_ipv4 == 0)
ogs_socknode_add(&list, AF_INET, addr);
ogs_socknode_add(
&list, AF_INET, addr,
is_option ? &option : NULL);
if (ogs_app()->parameter.no_ipv6 == 0)
ogs_socknode_add(&list6, AF_INET6, addr);
ogs_socknode_add(
&list6, AF_INET6, addr,
is_option ? &option : NULL);
ogs_freeaddrinfo(addr);
}
@ -233,7 +245,8 @@ int nssf_context_parse_config(void)
rv = ogs_socknode_probe(
ogs_app()->parameter.no_ipv4 ? NULL : &list,
ogs_app()->parameter.no_ipv6 ? NULL : &list6,
dev, port);
dev, port,
is_option ? &option : NULL);
ogs_assert(rv == OGS_OK);
}

View File

@ -161,6 +161,9 @@ int test_context_parse_config(void)
const char *dev = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_sockopt_t option;
bool is_option = false;
if (ogs_yaml_iter_type(&ngap_array) ==
YAML_MAPPING_NODE) {
memcpy(&ngap_iter, &ngap_array,
@ -217,6 +220,11 @@ int test_context_parse_config(void)
if (v) port = atoi(v);
} else if (!strcmp(ngap_key, "dev")) {
dev = ogs_yaml_iter_value(&ngap_iter);
} else if (!strcmp(ngap_key, "option")) {
rv = ogs_app_config_parse_sockopt(
&ngap_iter, &option);
if (rv != OGS_OK) return rv;
is_option = true;
} else
ogs_warn("unknown key `%s`", ngap_key);
}
@ -231,10 +239,12 @@ int test_context_parse_config(void)
if (addr) {
if (ogs_app()->parameter.no_ipv4 == 0)
ogs_socknode_add(
&self.ngap_list, AF_INET, addr);
&self.ngap_list, AF_INET, addr,
is_option ? &option : NULL);
if (ogs_app()->parameter.no_ipv6 == 0)
ogs_socknode_add(
&self.ngap_list6, AF_INET6, addr);
&self.ngap_list6, AF_INET6, addr,
is_option ? &option : NULL);
ogs_freeaddrinfo(addr);
}
@ -244,7 +254,8 @@ int test_context_parse_config(void)
NULL : &self.ngap_list,
ogs_app()->parameter.no_ipv6 ?
NULL : &self.ngap_list6,
dev, port);
dev, port,
is_option ? &option : NULL);
ogs_assert(rv == OGS_OK);
}
@ -258,7 +269,7 @@ int test_context_parse_config(void)
NULL : &self.ngap_list,
ogs_app()->parameter.no_ipv6 ?
NULL : &self.ngap_list6,
NULL, self.ngap_port);
NULL, self.ngap_port, NULL);
ogs_assert(rv == OGS_OK);
}
} if (!strcmp(amf_key, "tai")) {
@ -545,6 +556,9 @@ int test_context_parse_config(void)
const char *dev = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_sockopt_t option;
bool is_option = false;
if (ogs_yaml_iter_type(&s1ap_array) ==
YAML_MAPPING_NODE) {
memcpy(&s1ap_iter, &s1ap_array,
@ -601,6 +615,11 @@ int test_context_parse_config(void)
if (v) port = atoi(v);
} else if (!strcmp(s1ap_key, "dev")) {
dev = ogs_yaml_iter_value(&s1ap_iter);
} else if (!strcmp(s1ap_key, "option")) {
rv = ogs_app_config_parse_sockopt(
&s1ap_iter, &option);
if (rv != OGS_OK) return rv;
is_option = true;
} else
ogs_warn("unknown key `%s`", s1ap_key);
}
@ -615,10 +634,12 @@ int test_context_parse_config(void)
if (addr) {
if (ogs_app()->parameter.no_ipv4 == 0)
ogs_socknode_add(
&self.s1ap_list, AF_INET, addr);
&self.s1ap_list, AF_INET, addr,
is_option ? &option : NULL);
if (ogs_app()->parameter.no_ipv6 == 0)
ogs_socknode_add(
&self.s1ap_list6, AF_INET6, addr);
&self.s1ap_list6, AF_INET6, addr,
is_option ? &option : NULL);
ogs_freeaddrinfo(addr);
}
@ -628,7 +649,8 @@ int test_context_parse_config(void)
NULL : &self.s1ap_list,
ogs_app()->parameter.no_ipv6 ?
NULL : &self.s1ap_list6,
dev, port);
dev, port,
is_option ? &option : NULL);
ogs_assert(rv == OGS_OK);
}
@ -642,7 +664,7 @@ int test_context_parse_config(void)
NULL : &self.s1ap_list,
ogs_app()->parameter.no_ipv6 ?
NULL : &self.s1ap_list6,
NULL, self.s1ap_port);
NULL, self.s1ap_port, NULL);
ogs_assert(rv == OGS_OK);
}
} else if (!strcmp(mme_key, "tai")) {

View File

@ -47,9 +47,11 @@ ogs_socknode_t *test_gtpu_server(int index, int family)
node = ogs_socknode_new(addr);
ogs_assert(node);
sock = ogs_udp_server(node, false);
sock = ogs_udp_server(node->addr, NULL);
ogs_assert(sock);
node->sock = sock;
return node;
}

View File

@ -24,6 +24,7 @@ ogs_socknode_t *testsctp_server(const char *ipstr, int port)
int rv;
ogs_sockaddr_t *addr = NULL;
ogs_socknode_t *node = NULL;
ogs_sock_t *sock = NULL;
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, ipstr, port, 0);
ogs_assert(rv == OGS_OK);
@ -31,8 +32,11 @@ ogs_socknode_t *testsctp_server(const char *ipstr, int port)
node = ogs_socknode_new(addr);
ogs_assert(node);
ogs_sctp_server(SOCK_SEQPACKET, node);
ogs_assert(node->sock);
sock = ogs_sctp_server(SOCK_SEQPACKET, node->addr, NULL);
ogs_assert(sock);
node->sock = sock;
node->cleanup = ogs_sctp_destroy;
return node;
}
@ -42,6 +46,7 @@ ogs_socknode_t *testsctp_client(const char *ipstr, int port)
int rv;
ogs_sockaddr_t *addr = NULL;
ogs_socknode_t *node = NULL;
ogs_sock_t *sock = NULL;
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, ipstr, port, 0);
ogs_assert(rv == OGS_OK);
@ -49,8 +54,67 @@ ogs_socknode_t *testsctp_client(const char *ipstr, int port)
node = ogs_socknode_new(addr);
ogs_assert(node);
ogs_sctp_client(SOCK_STREAM, node);
ogs_assert(node->sock);
sock = ogs_sctp_client(SOCK_STREAM, node->addr, NULL);
ogs_assert(sock);
node->sock = sock;
node->cleanup = ogs_sctp_destroy;
return node;
}
ogs_socknode_t *tests1ap_client(int family)
{
int rv;
ogs_sockaddr_t *addr = NULL;
ogs_socknode_t *node = NULL;
ogs_sock_t *sock = NULL;
if (family == AF_INET6)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(&addr, test_self()->s1ap_addr6));
else
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(&addr, test_self()->s1ap_addr));
ogs_assert(addr);
node = ogs_socknode_new(addr);
ogs_assert(node);
sock = ogs_sctp_client(SOCK_STREAM, node->addr, NULL);
ogs_assert(sock);
node->sock = sock;
node->cleanup = ogs_sctp_destroy;
return node;
}
ogs_socknode_t *testngap_client(int family)
{
int rv;
ogs_sockaddr_t *addr = NULL;
ogs_socknode_t *node = NULL;
ogs_sock_t *sock = NULL;
if (family == AF_INET6)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(&addr, test_self()->ngap_addr6));
else
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(&addr, test_self()->ngap_addr));
ogs_assert(addr);
node = ogs_socknode_new(addr);
ogs_assert(node);
sock = ogs_sctp_client(SOCK_STREAM, node->addr, NULL);
ogs_assert(sock);
node->sock = sock;
node->cleanup = ogs_sctp_destroy;
return node;
}
@ -99,51 +163,3 @@ int testsctp_send(ogs_socknode_t *node, ogs_pkbuf_t *pkbuf,
return OGS_OK;
}
ogs_socknode_t *tests1ap_client(int family)
{
int rv;
ogs_sockaddr_t *addr = NULL;
ogs_socknode_t *node = NULL;
if (family == AF_INET6)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(&addr, test_self()->s1ap_addr6));
else
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(&addr, test_self()->s1ap_addr));
ogs_assert(addr);
node = ogs_socknode_new(addr);
ogs_assert(node);
ogs_sctp_client(SOCK_STREAM, node);
ogs_assert(node->sock);
return node;
}
ogs_socknode_t *testngap_client(int family)
{
int rv;
ogs_sockaddr_t *addr = NULL;
ogs_socknode_t *node = NULL;
if (family == AF_INET6)
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(&addr, test_self()->ngap_addr6));
else
ogs_assert(OGS_OK ==
ogs_copyaddrinfo(&addr, test_self()->ngap_addr));
ogs_assert(addr);
node = ogs_socknode_new(addr);
ogs_assert(node);
ogs_sctp_client(SOCK_STREAM, node);
ogs_assert(node->sock);
return node;
}

View File

@ -28,14 +28,13 @@ extern ogs_sockaddr_t ogs_test_sctp_last_addr;
ogs_socknode_t *testsctp_server(const char *ipstr, int port);
ogs_socknode_t *testsctp_client(const char *ipstr, int port);
ogs_socknode_t *tests1ap_client(int family);
ogs_socknode_t *testngap_client(int family);
int testsctp_send(ogs_socknode_t *node, ogs_pkbuf_t *pkbuf,
int ppid, uint16_t stream_no, int type);
ogs_pkbuf_t *testsctp_read(ogs_socknode_t *node, int type);
ogs_socknode_t *tests1ap_client(int family);
ogs_socknode_t *testngap_client(int family);
#define testenb_s1ap_client(x) testsctp_client(x, OGS_S1AP_SCTP_PORT)
#define testenb_s1ap_read(x) testsctp_read(x, 0);
#define testenb_s1ap_send(x, y) \
testsctp_send(x, y, OGS_SCTP_S1AP_PPID, 0, 0)

View File

@ -62,13 +62,13 @@ static void test1_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, OGS_OK, rv);
server[i] = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, server[i]);
ogs_udp_server(server[i], false, false);
server[i]->sock = ogs_udp_server(server[i]->addr, NULL);
ABTS_PTR_NOTNULL(tc, server[i]->sock);
rv = ogs_getaddrinfo(&addr, AF_INET, "127.0.0.1", PORT+i, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
client[i] = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, client[i]);
ogs_udp_client(client[i]);
client[i]->sock = ogs_udp_client(client[i]->addr, NULL);
ABTS_PTR_NOTNULL(tc, client[i]->sock);
}
@ -132,8 +132,7 @@ static void test1_func(abts_case *tc, void *data)
}
#endif
static ogs_socknode_t *test2_server, *test2_client;
static ogs_sock_t *test2_accept;
static ogs_sock_t *test2_client;
static int test2_okay = 1;
static void test2_handler(short when, ogs_socket_t fd, void *data)
@ -147,7 +146,7 @@ static void test2_handler(short when, ogs_socket_t fd, void *data)
len = ogs_send(fd, test, (int)strlen(test) + 1, 0);
if (len > 0) {
ogs_socknode_free(test2_client);
ogs_sock_destroy(test2_client);
}
test2_okay = 0;
@ -157,29 +156,30 @@ static void test2_func(abts_case *tc, void *data)
{
int rv;
ogs_poll_t *poll;
ogs_sock_t *server, *client, *accept;
ogs_sockaddr_t *addr;
ogs_pollset_t *pollset = ogs_pollset_create(512);
ABTS_PTR_NOTNULL(tc, pollset);
rv = ogs_getaddrinfo(&addr, AF_INET, "127.0.0.1", PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
test2_server = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, test2_server);
ogs_tcp_server(test2_server);
ABTS_PTR_NOTNULL(tc, test2_server->sock);
server = ogs_tcp_server(addr, NULL);
ABTS_PTR_NOTNULL(tc, server);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = ogs_getaddrinfo(&addr, AF_INET, "127.0.0.1", PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
test2_client = ogs_socknode_new(addr);
test2_client = ogs_tcp_client(addr, NULL);
ABTS_PTR_NOTNULL(tc, test2_client);
ogs_tcp_client(test2_client);
ABTS_PTR_NOTNULL(tc, test2_client->sock);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
test2_accept = ogs_sock_accept(test2_server->sock);
ABTS_PTR_NOTNULL(tc, test2_accept);
accept = ogs_sock_accept(server);
ABTS_PTR_NOTNULL(tc, accept);
poll = ogs_pollset_add(pollset, OGS_POLLOUT,
test2_accept->fd, test2_handler, tc);
accept->fd, test2_handler, tc);
ABTS_PTR_NOTNULL(tc, poll);
rv = ogs_pollset_poll(pollset, OGS_INFINITE_TIME);
@ -189,8 +189,8 @@ static void test2_func(abts_case *tc, void *data)
ogs_pollset_remove(poll);
ogs_sock_destroy(test2_accept);
ogs_socknode_free(test2_server);
ogs_sock_destroy(accept);
ogs_sock_destroy(server);
ogs_pollset_destroy(pollset);
}
@ -249,7 +249,7 @@ static void test4_main(void *data)
ogs_sockaddr_t *sa;
ssize_t size;
udp = ogs_udp_socket(AF_INET, NULL);
udp = ogs_sock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
ABTS_PTR_NOTNULL(tc, udp);
rv = ogs_getaddrinfo(&sa, AF_INET, NULL, PORT, 0);
@ -291,9 +291,7 @@ static void test4_func(abts_case *tc, void *data)
rv = ogs_getaddrinfo(&addr, AF_INET, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node, false);
udp = ogs_udp_server(addr, NULL);
ABTS_PTR_NOTNULL(tc, udp);
poll = ogs_pollset_add(pollset, OGS_POLLIN, udp->fd, test4_handler, tc);
@ -306,7 +304,11 @@ static void test4_func(abts_case *tc, void *data)
ogs_thread_destroy(test4_thread);
ogs_pollset_remove(poll);
ogs_socknode_free(node);
ogs_sock_destroy(udp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
ogs_pollset_destroy(pollset);
}
@ -460,57 +462,59 @@ static void test8_func(abts_case *tc, void *data)
{
int rv;
ogs_poll_t *write1, *write2, *write3;
ogs_sock_t *server, *client1, *client2, *client3;
ogs_sock_t *accept1, *accept2, *accept3;
ogs_sockaddr_t *addr;
ogs_pollset_t *pollset = ogs_pollset_create(512);
ABTS_PTR_NOTNULL(tc, pollset);
rv = ogs_getaddrinfo(&addr, AF_INET, "127.0.0.1", PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
test8_server = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, test8_server);
ogs_tcp_server(test8_server);
ABTS_PTR_NOTNULL(tc, test8_server->sock);
server = ogs_tcp_server(addr, NULL);
ABTS_PTR_NOTNULL(tc, server);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = ogs_getaddrinfo(&addr, AF_INET, "127.0.0.1", PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
test8_client1 = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, test8_client1);
ogs_tcp_client(test8_client1);
ABTS_PTR_NOTNULL(tc, test8_client1->sock);
client1 = ogs_tcp_client(addr, NULL);
ABTS_PTR_NOTNULL(tc, client1);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
test8_accept1 = ogs_sock_accept(test8_server->sock);
ABTS_PTR_NOTNULL(tc, test8_accept1);
accept1 = ogs_sock_accept(server);
ABTS_PTR_NOTNULL(tc, accept1);
rv = ogs_getaddrinfo(&addr, AF_INET, "127.0.0.1", PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
test8_client2 = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, test8_client2);
ogs_tcp_client(test8_client2);
ABTS_PTR_NOTNULL(tc, test8_client2->sock);
client2 = ogs_tcp_client(addr, NULL);
ABTS_PTR_NOTNULL(tc, client2);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
test8_accept2 = ogs_sock_accept(test8_server->sock);
ABTS_PTR_NOTNULL(tc, test8_accept2);
accept2 = ogs_sock_accept(server);
ABTS_PTR_NOTNULL(tc, accept2);
rv = ogs_getaddrinfo(&addr, AF_INET, "127.0.0.1", PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
test8_client3 = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, test8_client3);
ogs_tcp_client(test8_client3);
ABTS_PTR_NOTNULL(tc, test8_client3->sock);
client3 = ogs_tcp_client(addr, NULL);
ABTS_PTR_NOTNULL(tc, client3);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
test8_accept3 = ogs_sock_accept(test8_server->sock);
ABTS_PTR_NOTNULL(tc, test8_accept3);
accept3 = ogs_sock_accept(server);
ABTS_PTR_NOTNULL(tc, accept3);
write1 = ogs_pollset_add(pollset, OGS_POLLOUT,
test8_accept1->fd, test8_handler, NULL);
accept1->fd, test8_handler, NULL);
ABTS_PTR_NOTNULL(tc, write1);
write2 = ogs_pollset_add(pollset, OGS_POLLOUT,
test8_accept2->fd, test8_handler, NULL);
accept2->fd, test8_handler, NULL);
ABTS_PTR_NOTNULL(tc, write2);
write3 = ogs_pollset_add(pollset, OGS_POLLOUT,
test8_accept3->fd, test8_handler, NULL);
accept3->fd, test8_handler, NULL);
ABTS_PTR_NOTNULL(tc, write3);
rv = ogs_pollset_poll(pollset, OGS_INFINITE_TIME);
@ -523,11 +527,11 @@ static void test8_func(abts_case *tc, void *data)
ogs_pollset_remove(write3);
write2 = ogs_pollset_add(pollset, OGS_POLLOUT,
test8_accept2->fd, test8_handler, NULL);
accept2->fd, test8_handler, NULL);
ABTS_PTR_NOTNULL(tc, write2);
write3 = ogs_pollset_add(pollset, OGS_POLLOUT,
test8_accept3->fd, test8_handler, NULL);
accept3->fd, test8_handler, NULL);
ABTS_PTR_NOTNULL(tc, write3);
rv = ogs_pollset_poll(pollset, OGS_INFINITE_TIME);
@ -539,7 +543,7 @@ static void test8_func(abts_case *tc, void *data)
ogs_pollset_remove(write3);
write3 = ogs_pollset_add(pollset, OGS_POLLOUT,
test8_accept3->fd, test8_handler, NULL);
accept3->fd, test8_handler, NULL);
ABTS_PTR_NOTNULL(tc, write3);
rv = ogs_pollset_poll(pollset, OGS_INFINITE_TIME);
@ -550,17 +554,17 @@ static void test8_func(abts_case *tc, void *data)
ogs_pollset_remove(write3);
write1 = ogs_pollset_add(pollset, OGS_POLLOUT,
test8_accept1->fd, test8_handler_with_remove,
accept1->fd, test8_handler_with_remove,
ogs_pollset_self_handler_data());
ABTS_PTR_NOTNULL(tc, write1);
write2 = ogs_pollset_add(pollset, OGS_POLLOUT,
test8_accept2->fd, test8_handler_with_remove,
accept2->fd, test8_handler_with_remove,
ogs_pollset_self_handler_data());
ABTS_PTR_NOTNULL(tc, write2);
write3 = ogs_pollset_add(pollset, OGS_POLLOUT,
test8_accept3->fd, test8_handler_with_remove,
accept3->fd, test8_handler_with_remove,
ogs_pollset_self_handler_data());
ABTS_PTR_NOTNULL(tc, write3);
@ -570,12 +574,12 @@ static void test8_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, 10, test8_okay);
write1 = ogs_pollset_add(pollset, OGS_POLLOUT,
test8_accept1->fd, test8_handler_with_remove,
accept1->fd, test8_handler_with_remove,
ogs_pollset_self_handler_data());
ABTS_PTR_NOTNULL(tc, write1);
write2 = ogs_pollset_add(pollset, OGS_POLLOUT,
test8_accept2->fd, test8_handler_with_remove,
accept2->fd, test8_handler_with_remove,
ogs_pollset_self_handler_data());
ABTS_PTR_NOTNULL(tc, write2);
@ -585,7 +589,7 @@ static void test8_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, 12, test8_okay);
write1 = ogs_pollset_add(pollset, OGS_POLLOUT,
test8_accept1->fd, test8_handler_with_remove,
accept1->fd, test8_handler_with_remove,
ogs_pollset_self_handler_data());
ABTS_PTR_NOTNULL(tc, write1);
@ -595,17 +599,17 @@ static void test8_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, 13, test8_okay);
write1 = ogs_pollset_add(pollset, OGS_POLLIN|OGS_POLLOUT,
test8_accept1->fd, test8_handler_with_remove,
accept1->fd, test8_handler_with_remove,
ogs_pollset_self_handler_data());
ABTS_PTR_NOTNULL(tc, write1);
write2 = ogs_pollset_add(pollset, OGS_POLLIN|OGS_POLLOUT,
test8_accept2->fd, test8_handler_with_remove,
accept2->fd, test8_handler_with_remove,
ogs_pollset_self_handler_data());
ABTS_PTR_NOTNULL(tc, write2);
write3 = ogs_pollset_add(pollset, OGS_POLLIN|OGS_POLLOUT,
test8_accept3->fd, test8_handler_with_remove,
accept3->fd, test8_handler_with_remove,
ogs_pollset_self_handler_data());
ABTS_PTR_NOTNULL(tc, write3);
@ -615,12 +619,12 @@ static void test8_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, 16, test8_okay);
write2 = ogs_pollset_add(pollset, OGS_POLLIN|OGS_POLLOUT,
test8_accept2->fd, test8_handler_with_remove,
accept2->fd, test8_handler_with_remove,
ogs_pollset_self_handler_data());
ABTS_PTR_NOTNULL(tc, write2);
write3 = ogs_pollset_add(pollset, OGS_POLLIN|OGS_POLLOUT,
test8_accept3->fd, test8_handler_with_remove,
accept3->fd, test8_handler_with_remove,
ogs_pollset_self_handler_data());
ABTS_PTR_NOTNULL(tc, write3);
@ -630,7 +634,7 @@ static void test8_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, 18, test8_okay);
write3 = ogs_pollset_add(pollset, OGS_POLLIN|OGS_POLLOUT,
test8_accept3->fd, test8_handler_with_remove,
accept3->fd, test8_handler_with_remove,
ogs_pollset_self_handler_data());
ABTS_PTR_NOTNULL(tc, write3);
@ -639,16 +643,16 @@ static void test8_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, 19, test8_okay);
ogs_socknode_free(test8_client1);
ogs_sock_destroy(test8_accept1);
ogs_sock_destroy(client1);
ogs_sock_destroy(accept1);
ogs_socknode_free(test8_client2);
ogs_sock_destroy(test8_accept2);
ogs_sock_destroy(client2);
ogs_sock_destroy(accept2);
ogs_socknode_free(test8_client3);
ogs_sock_destroy(test8_accept3);
ogs_sock_destroy(client3);
ogs_sock_destroy(accept3);
ogs_socknode_free(test8_server);
ogs_sock_destroy(server);
ogs_pollset_destroy(pollset);
}

View File

@ -34,31 +34,30 @@ static void test1_func(abts_case *tc, void *data)
int rv;
ogs_sock_t *udp;
ogs_sockaddr_t *addr;
ogs_socknode_t *node;
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node, false);
udp = ogs_udp_server(addr, NULL);
ABTS_PTR_NOTNULL(tc, udp);
ogs_socknode_free(node);
ogs_sock_destroy(udp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, "127.0.0.1", PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node, false);
udp = ogs_udp_server(addr, NULL);
ABTS_PTR_NOTNULL(tc, udp);
ogs_socknode_free(node);
ogs_sock_destroy(udp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, "::1", PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node, false);
udp = ogs_udp_server(addr, NULL);
ABTS_PTR_NOTNULL(tc, udp);
ogs_socknode_free(node);
ogs_sock_destroy(udp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
static ogs_thread_t *test2_thread;
@ -68,21 +67,20 @@ static void test2_main(void *data)
abts_case *tc = data;
ogs_sock_t *tcp;
ogs_sockaddr_t *addr;
ogs_socknode_t *node;
char str[STRLEN];
ssize_t size;
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, "::1", PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
tcp = ogs_tcp_client(node);
tcp = ogs_tcp_client(addr, NULL);
ABTS_PTR_NOTNULL(tc, tcp);
size = ogs_recv(tcp->fd, str, STRLEN, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ogs_socknode_free(node);
ogs_sock_destroy(tcp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
static void test2_func(abts_case *tc, void *data)
@ -95,9 +93,7 @@ static void test2_func(abts_case *tc, void *data)
rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
tcp = ogs_tcp_server(node);
tcp = ogs_tcp_server(addr, NULL);
ABTS_PTR_NOTNULL(tc, tcp);
test2_thread = ogs_thread_create(test2_main, tc);
@ -112,7 +108,9 @@ static void test2_func(abts_case *tc, void *data)
ogs_thread_destroy(test2_thread);
ogs_sock_destroy(tcp2);
ogs_socknode_free(node);
ogs_sock_destroy(tcp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
static ogs_thread_t *test3_thread;
@ -127,7 +125,7 @@ static void test3_main(void *data)
rv = ogs_getaddrinfo(&addr, AF_INET, NULL, PORT, 0);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
udp = ogs_udp_socket(AF_INET, NULL);
udp = ogs_sock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
ABTS_PTR_NOTNULL(tc, udp);
size = ogs_sendto(udp->fd, DATASTR, strlen(DATASTR), 0, addr);
@ -146,15 +144,12 @@ static void test3_func(abts_case *tc, void *data)
ssize_t size;
ogs_sockaddr_t sa;
ogs_sockaddr_t *addr;
ogs_socknode_t *node;
char str[STRLEN];
char buf[OGS_ADDRSTRLEN];
rv = ogs_getaddrinfo(&addr, AF_INET, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node, false);
udp = ogs_udp_server(addr, NULL);
ABTS_PTR_NOTNULL(tc, udp);
test3_thread = ogs_thread_create(test3_main, tc);
@ -166,7 +161,10 @@ static void test3_func(abts_case *tc, void *data)
ogs_thread_destroy(test3_thread);
ogs_socknode_free(node);
ogs_sock_destroy(udp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
static ogs_thread_t *test4_thread;
@ -176,15 +174,12 @@ static void test4_main(void *data)
abts_case *tc = data;
ogs_sock_t *udp;
ogs_sockaddr_t *addr;
ogs_socknode_t *node;
char str[STRLEN];
ssize_t size;
rv = ogs_getaddrinfo(&addr, AF_INET, NULL, PORT, 0);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_client(node);
udp = ogs_udp_client(addr, NULL);
ABTS_PTR_NOTNULL(tc, udp);
size = ogs_send(udp->fd, DATASTR, strlen(DATASTR), 0);
@ -193,7 +188,10 @@ static void test4_main(void *data)
size = ogs_recv(udp->fd, str, STRLEN, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ogs_socknode_free(node);
ogs_sock_destroy(udp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
static void test4_func(abts_case *tc, void *data)
@ -203,15 +201,12 @@ static void test4_func(abts_case *tc, void *data)
ssize_t size;
ogs_sockaddr_t sa;
ogs_sockaddr_t *addr;
ogs_socknode_t *node;
char str[STRLEN];
char buf[OGS_ADDRSTRLEN];
rv = ogs_getaddrinfo(&addr, AF_INET, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node, false);
udp = ogs_udp_server(addr, NULL);
ABTS_PTR_NOTNULL(tc, udp);
test4_thread = ogs_thread_create(test4_main, tc);
@ -226,7 +221,10 @@ static void test4_func(abts_case *tc, void *data)
ogs_thread_destroy(test4_thread);
ogs_socknode_free(node);
ogs_sock_destroy(udp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
static ogs_thread_t *test5_thread;
@ -242,10 +240,10 @@ static void test5_main(void *data)
rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, PORT2, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node, false);
udp = ogs_udp_server(addr, NULL);
ABTS_PTR_NOTNULL(tc, udp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, PORT, 0);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
@ -260,7 +258,7 @@ static void test5_main(void *data)
size = ogs_recv(udp->fd, str, STRLEN, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ogs_socknode_free(node);
ogs_sock_destroy(udp);
}
static void test5_func(abts_case *tc, void *data)
@ -269,16 +267,15 @@ static void test5_func(abts_case *tc, void *data)
int rv;
ssize_t size;
ogs_sockaddr_t sa, *addr;
ogs_socknode_t *node;
char str[STRLEN];
char buf[OGS_ADDRSTRLEN];
rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node, false);
udp = ogs_udp_server(addr, NULL);
ABTS_PTR_NOTNULL(tc, udp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, PORT2, 0);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
@ -299,7 +296,7 @@ static void test5_func(abts_case *tc, void *data)
ogs_thread_destroy(test5_thread);
ogs_socknode_free(node);
ogs_sock_destroy(udp);
}
static void test6_func(abts_case *tc, void *data)
@ -389,14 +386,14 @@ static void test7_func(abts_case *tc, void *data)
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, "localhost", PORT, 0);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_add(&list, AF_INET, addr);
node = ogs_socknode_add(&list, AF_INET, addr, NULL);
ABTS_PTR_NOTNULL(tc, node);
ogs_freeaddrinfo(addr);
ogs_socknode_remove_all(&list);
rv = ogs_socknode_probe(&list, &list6, NULL, PORT);
rv = ogs_socknode_probe(&list, &list6, NULL, PORT, NULL);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
ogs_socknode_remove_all(&list);

View File

@ -38,9 +38,11 @@ ogs_socknode_t *test_epdg_server(uint16_t port)
node = ogs_socknode_new(addr);
ogs_assert(node);
sock = ogs_udp_server(node, false);
sock = ogs_udp_server(node->addr, NULL);
ogs_assert(sock);
node->sock = sock;
return node;
}

View File

@ -39,28 +39,27 @@ static void test1_func(abts_case *tc, void *data)
{
ogs_sock_t *sctp;
ogs_sockaddr_t *addr;
ogs_socknode_t *node;
int rv;
sctp = ogs_sctp_socket(AF_INET6, SOCK_SEQPACKET, NULL);
sctp = ogs_sctp_socket(AF_INET6, SOCK_SEQPACKET);
ABTS_PTR_NOTNULL(tc, sctp);
ogs_sctp_destroy(sctp);
rv = ogs_getaddrinfo(&addr, AF_INET, NULL, TEST1_PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
sctp = ogs_sctp_server(SOCK_STREAM, node);
sctp = ogs_sctp_server(SOCK_STREAM, addr, NULL);
ABTS_PTR_NOTNULL(tc, sctp);
ogs_socknode_free(node);
ogs_sctp_destroy(sctp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, NULL, TEST1_PORT2, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
sctp = ogs_sctp_server(SOCK_SEQPACKET, node);
sctp = ogs_sctp_server(SOCK_SEQPACKET, addr, NULL);
ABTS_PTR_NOTNULL(tc, sctp);
ogs_socknode_free(node);
ogs_sctp_destroy(sctp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
static ogs_thread_t *test2_thread;
@ -74,14 +73,11 @@ static void test2_main(void *data)
uint32_t ppid;
ogs_sctp_info_t sinfo;
ogs_sockaddr_t *addr;
ogs_socknode_t *node;
ogs_sockaddr_t from;
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, NULL, TEST2_PORT, 0);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
sctp = ogs_sctp_client(SOCK_SEQPACKET, node);
sctp = ogs_sctp_client(SOCK_SEQPACKET, addr, NULL);
ABTS_PTR_NOTNULL(tc, sctp);
size = ogs_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo);
@ -90,7 +86,9 @@ static void test2_main(void *data)
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
#endif
ogs_socknode_free(node);
ogs_sctp_destroy(sctp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
static void test2_func(abts_case *tc, void *data)
@ -99,13 +97,10 @@ static void test2_func(abts_case *tc, void *data)
ogs_sock_t *sctp, *sctp2;
ssize_t size;
ogs_sockaddr_t *addr;
ogs_socknode_t *node;
rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, TEST2_PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
sctp = ogs_sctp_server(SOCK_STREAM, node);
sctp = ogs_sctp_server(SOCK_STREAM, addr, NULL);
ABTS_PTR_NOTNULL(tc, sctp);
test2_thread = ogs_thread_create(test2_main, tc);
@ -120,7 +115,10 @@ static void test2_func(abts_case *tc, void *data)
ogs_thread_destroy(test2_thread);
ogs_sctp_destroy(sctp2);
ogs_socknode_free(node);
ogs_sctp_destroy(sctp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
static ogs_thread_t *test3_thread;
@ -135,9 +133,12 @@ static void test3_main(void *data)
ssize_t size;
int rc;
sctp = ogs_sctp_socket(AF_INET, SOCK_SEQPACKET, NULL);
sctp = ogs_sctp_socket(AF_INET, SOCK_SEQPACKET);
ABTS_PTR_NOTNULL(tc, sctp);
rv = ogs_sctp_nodelay(sctp, 1);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = ogs_getaddrinfo(&to, AF_INET, NULL, TEST3_PORT, 0);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
@ -156,16 +157,13 @@ static void test3_func(abts_case *tc, void *data)
int rv;
ssize_t size;
ogs_sockaddr_t from, *addr;
ogs_socknode_t *node;
char str[STRLEN];
char buf[OGS_ADDRSTRLEN];
ogs_sctp_info_t sinfo;
rv = ogs_getaddrinfo(&addr, AF_INET, NULL, TEST3_PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
sctp = ogs_sctp_server(SOCK_SEQPACKET, node);
sctp = ogs_sctp_server(SOCK_SEQPACKET, addr, NULL);
ABTS_PTR_NOTNULL(tc, sctp);
test3_thread = ogs_thread_create(test3_main, tc);
@ -179,7 +177,10 @@ static void test3_func(abts_case *tc, void *data)
ogs_thread_destroy(test3_thread);
ogs_socknode_free(node);
ogs_sctp_destroy(sctp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
static ogs_thread_t *test4_thread;
@ -189,16 +190,13 @@ static void test4_main(void *data)
abts_case *tc = data;
ogs_sock_t *sctp;
ogs_sockaddr_t *addr;
ogs_socknode_t *node;
char str[STRLEN];
ssize_t size;
ogs_sctp_info_t sinfo;
rv = ogs_getaddrinfo(&addr, AF_UNSPEC, NULL, TEST4_PORT, 0);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
sctp = ogs_sctp_client(SOCK_STREAM, node);
sctp = ogs_sctp_client(SOCK_STREAM, addr, NULL);
ABTS_PTR_NOTNULL(tc, sctp);
size = ogs_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), NULL, PPID, 0);
@ -210,7 +208,10 @@ static void test4_main(void *data)
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
#endif
ogs_socknode_free(node);
ogs_sctp_destroy(sctp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
static void test4_func(abts_case *tc, void *data)
@ -219,16 +220,13 @@ static void test4_func(abts_case *tc, void *data)
ogs_sock_t *sctp;
ssize_t size;
ogs_sockaddr_t from, *addr;
ogs_socknode_t *node;
char str[STRLEN];
ogs_sctp_info_t sinfo;
char buf[OGS_ADDRSTRLEN];
rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, TEST4_PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
sctp = ogs_sctp_server(SOCK_SEQPACKET, node);
sctp = ogs_sctp_server(SOCK_SEQPACKET, addr, NULL);
ABTS_PTR_NOTNULL(tc, sctp);
test4_thread = ogs_thread_create(test4_main, tc);
@ -245,7 +243,11 @@ static void test4_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ogs_thread_destroy(test4_thread);
ogs_socknode_free(node);
ogs_sctp_destroy(sctp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
static ogs_thread_t *test5_thread;
@ -256,17 +258,16 @@ static void test5_main(void *data)
ogs_sock_t *sctp;
char str[STRLEN];
ogs_sockaddr_t from, *remote_addr, *addr;
ogs_socknode_t *node;
ogs_sctp_info_t sinfo;
ssize_t size;
char buf[OGS_ADDRSTRLEN];
rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, TEST5_PORT2, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
sctp = ogs_sctp_server(SOCK_SEQPACKET, node);
sctp = ogs_sctp_server(SOCK_SEQPACKET, addr, NULL);
ABTS_PTR_NOTNULL(tc, sctp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, TEST5_PORT, 0);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
@ -293,7 +294,7 @@ static void test5_main(void *data)
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
#endif
ogs_socknode_free(node);
ogs_sctp_destroy(sctp);
}
static void test5_func(abts_case *tc, void *data)
@ -303,7 +304,6 @@ static void test5_func(abts_case *tc, void *data)
ssize_t size;
ogs_sockaddr_t from;
ogs_sockaddr_t *addr;
ogs_socknode_t *node;
socklen_t addrlen;
char str[STRLEN];
ogs_sctp_info_t sinfo;
@ -311,9 +311,7 @@ static void test5_func(abts_case *tc, void *data)
rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, TEST5_PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
sctp = ogs_sctp_server(SOCK_SEQPACKET, node);
sctp = ogs_sctp_server(SOCK_SEQPACKET, addr, NULL);
ABTS_PTR_NOTNULL(tc, sctp);
test5_thread = ogs_thread_create(test5_main, tc);
@ -331,7 +329,11 @@ static void test5_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ogs_thread_destroy(test5_thread);
ogs_socknode_free(node);
ogs_sctp_destroy(sctp);
rv = ogs_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
abts_suite *test_sctp(abts_suite *suite)