=head1 NAME Vici::Session - Perl binding for the strongSwan VICI configuration interface =head1 DESCRIPTION The Vici::Session module allows a Perl script to communicate with the open source strongSwan IPsec daemon (https://www.strongswan.org) via the documented Versatile IKE Configuration Interface (VICI). VICI allows the configuration, management and monitoring of multiple IPsec connections. =head1 INSTALLATION To install this module type the following: perl Makefile.PL make make install =head1 DEPENDENCIES This module requires the standard networking module: IO::Socket::UNIX =head1 METHODS The following examples show the use of the Vici::Session interface in a a "net-net" connection between the VPN gateways "moon" and "sun". =cut use strict; use warnings; use IO::Socket::UNIX; use Vici::Message; use Vici::Session; my $moon_key = "-----BEGIN RSA PRIVATE KEY-----\n" . "MIIEowIBAAKCAQEApHwF+sUXQdH+WwYzdPMzpjuwhGGvHgsmBah1IQsPsddL9gZy" . "gerzpTM1vvQ4kbRuvE3SZWLf9uKEbiQV9IABr87L9JAva56EHIAiUMuG8WizVbIK" . "IhQlZc8S2mIwAW0Jc6EmnoJv9j6F/tVD9+6xvMJbwHLi0h7BUO9tBVLPy72YeGNB" . "Y6Cob4CrOuFOJyACezJ7i9vZ+XzOfnXpu7qL0DgYP/n2maPEJGEivTFunkJD/mJ8" . "DecyLTQcchsCj2118BMuf2qjVn4UWPCBBuhyYK5wsATB1ANeAtlFfgH+wsuHjZwt" . "TJru05lGHBZ3F2hZ9PO68hVHbIZZj6SB8X47nwIDAQABAoIBAAQDXqX6rxGVDQ6t" . "fQ3qbSUuKaVhOMOT5A6ZSJpQycY+CYVsLNkMoXszX6lUDhlH/Letcme03OAKMM77" . "JGn9wYzHj+RcrDuE95Y2bh/oh1dWhaGeoW6pbSwpvD0FzkQKpANlOCr/5bltVxmb" . "nHftI/sGBvUQGIal53ORE+jgV1+SK6I0oAIWiCpU2oZpYMAtp7WxOngsAJaGtk//" . "m2ckH+T8uVHwe9gJ9HZnEk+Io6BXScMNNrsbd2J+pQ75wQXfzHEzHAj+ElhWzhtc" . "5XefqHw/DfpPDX/lby3VoSoagqzsVuUx7LylgzIDxTsb9HQVOLjDzOQ+vn22Xj7g" . "UCEjwLkCgYEA2EZguuzJdxRIWBSnIyzpCzfqm0EgybpeLuJVfzWla0yKWI6AeLhW" . "cr+7o9UE8nCQHVffIrgjWksjc/S5FhzC9TYSHpPa8TPgebTQK4VxnP9Qkh/XRpJj" . "CqgJ8k2MYleHYxa+AKQv/25yNhLdowkNR0iU1kbiaYRJMP0WigAmdAUCgYEAwrJe" . "Y3LAawOkalJFMFTtLXsqZE91TFwMt9TQnzysGH3Q6+9N+qypS5KCes650+qgrwBV" . "RmRNc1ixylToP3B0BKY5OD/BwMx1L/zSO3x7I4ZDasCu33y2ukGLcVSxrxTPTGdd" . "8fhEiVO1CDXcM08/kSeQa049J8ziY3M+4NDchlMCgYEAw2VCO1923Tjb64gtQOBw" . "ZAxOz5nVz6urL9yYted33is2yq9kbqzMnbuQAYKRh6Ae9APRuwJ2HjvIehjdp5aw" . "pO4HDM00f7sI0ayEbu2PKfKZjotp6X6UMKqE4f8iGC9QSDvhyZ6NJs9YLHZ6+7NP" . "5dkzbyx3njFAFxxxYpikJSkCgYByShB8YlUvvKCcRRUWbRQZWa6l2brqizJwCz43" . "636+lcS5au2klAyBL0zm2Elfa+DNOe3U93Y7mrorIrJ+4v1H6We3bD3JdnvoIooq" . "n0UNsngKx3cf++6r4WQAsA3pz9ZsbFVKgEmDL58aZbuQZxnSlJ4DT5c4sN3IMVOc" . "1x5MvwKBgHudAaLvioIopBpYzOsK2OtEn6NQ7SwH0BLEUulHysaHqan5oExmM1bm" . "YeivMDc9hj0YLXA47ryQHTx4vB5Nv3TI/LoUG6VrCvZvocQOXe/n7TguwAjJj7ef" . "E55Gy8lXDRENyJMP1vif3N2iH8eQ1ASf8k/+gnBNkjSlYSSQUDfV\n" . "-----END RSA PRIVATE KEY-----\n"; my $moon_cert = "-----BEGIN CERTIFICATE-----\n" . "MIIEIjCCAwqgAwIBAgIBKzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJDSDEZ" . "MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS" . "b290IENBMB4XDTE0MDgyNzE0NDQ1NloXDTE5MDgyNjE0NDQ1NlowRjELMAkGA1UE" . "BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xHDAaBgNVBAMTE21vb24u" . "c3Ryb25nc3dhbi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCk" . "fAX6xRdB0f5bBjN08zOmO7CEYa8eCyYFqHUhCw+x10v2BnKB6vOlMzW+9DiRtG68" . "TdJlYt/24oRuJBX0gAGvzsv0kC9rnoQcgCJQy4bxaLNVsgoiFCVlzxLaYjABbQlz" . "oSaegm/2PoX+1UP37rG8wlvAcuLSHsFQ720FUs/LvZh4Y0FjoKhvgKs64U4nIAJ7" . "MnuL29n5fM5+dem7uovQOBg/+faZo8QkYSK9MW6eQkP+YnwN5zItNBxyGwKPbXXw" . "Ey5/aqNWfhRY8IEG6HJgrnCwBMHUA14C2UV+Af7Cy4eNnC1Mmu7TmUYcFncXaFn0" . "87ryFUdshlmPpIHxfjufAgMBAAGjggEaMIIBFjAJBgNVHRMEAjAAMAsGA1UdDwQE" . "AwIDqDAdBgNVHQ4EFgQU2CY9Iex8275aOQxbcMsDgCHerhMwbQYDVR0jBGYwZIAU" . "XafdcAZRMn7ntm2zteXgYOouTe+hSaRHMEUxCzAJBgNVBAYTAkNIMRkwFwYDVQQK" . "ExBMaW51eCBzdHJvbmdTd2FuMRswGQYDVQQDExJzdHJvbmdTd2FuIFJvb3QgQ0GC" . "AQAwHgYDVR0RBBcwFYITbW9vbi5zdHJvbmdzd2FuLm9yZzATBgNVHSUEDDAKBggr" . "BgEFBQcDATA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vY3JsLnN0cm9uZ3N3YW4u" . "b3JnL3N0cm9uZ3N3YW4uY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQCpnj6Nc+PuPLPi" . "4E3g5hyJkr5VZy7SSglcs1uyVP2mfwj6JR9SLd5+JOsL1aCTm0y9qLcqdbHBxG8i" . "LNLtwVKU3s1hV4EIO3saHe4XUEjxN9bDtLWEoeq5ipmYX8RJ/fXKR8/8vurBARP2" . "xu1+wqwEhymp4jBmF0LVovT1+o+GhH66zIJnx3zR9BtfMkaeL6804hrx2ygeopeo" . "buGvMDQ8HcnMB9OU7Y8fK0oY1kULl6hf36K5ApPA6766sRRKRvBSKlmViKSQTq5a" . "4c8gCWAZbtdT+N/fa8hKDlZt5q10EgjTqDfGTj50xKvAneq7XdfKmYYGnIWoNLY9" . "ga8NOzX8\n" . "-----END CERTIFICATE-----\n"; my $ca_cert = "-----BEGIN CERTIFICATE-----\n" . "MIIDuDCCAqCgAwIBAgIBADANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJDSDEZ" . "MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS" . "b290IENBMB4XDTA0MDkxMDEwMDExOFoXDTE5MDkwNzEwMDExOFowRTELMAkGA1UE" . "BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xGzAZBgNVBAMTEnN0cm9u" . "Z1N3YW4gUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL/y" . "X2LqPVZuWLPIeknK86xhz6ljd3NNhC2z+P1uoCP3sBMuZiZQEjFzhnKcbXxCeo2f" . "FnvhOOjrrisSuVkzuu82oxXD3fIkzuS7m9V4E10EZzgmKWIf+WuNRfbgAuUINmLc" . "4YGAXBQLPyzpP4Ou48hhz/YQo58Bics6PHy5v34qCVROIXDvqhj91P8g+pS+F21/" . "7P+CH2jRcVIEHZtG8M/PweTPQ95dPzpYd2Ov6SZ/U7EWmbMmT8VcUYn1aChxFmy5" . "gweVBWlkH6MP+1DeE0/tL5c87xo5KCeGK8Tdqpe7sBRC4pPEEHDQciTUvkeuJ1Pr" . "K+1LwdqRxo7HgMRiDw8CAwEAAaOBsjCBrzASBgNVHRMBAf8ECDAGAQH/AgEBMAsG" . "A1UdDwQEAwIBBjAdBgNVHQ4EFgQUXafdcAZRMn7ntm2zteXgYOouTe8wbQYDVR0j" . "BGYwZIAUXafdcAZRMn7ntm2zteXgYOouTe+hSaRHMEUxCzAJBgNVBAYTAkNIMRkw" . "FwYDVQQKExBMaW51eCBzdHJvbmdTd2FuMRswGQYDVQQDExJzdHJvbmdTd2FuIFJv" . "b3QgQ0GCAQAwDQYJKoZIhvcNAQELBQADggEBACOSmqEBtBLR9aV3UyCI8gmzR5in" . "Lte9aUXXS+qis6F2h2Stf4sN+Nl6Gj7REC6SpfEH4wWdwiUL5J0CJhyoOjQuDl3n" . "1Dw3dE4/zqMZdyDKEYTU75TmvusNJBdGsLkrf7EATAjoi/nrTOYPPhSUZvPp/D+Y" . "vORJ9Ej51GXlK1nwEB5iA8+tDYniNQn6BD1MEgIejzK+fbiy7braZB1kqhoEr2Si" . "7luBSnU912sw494E88a2EWbmMvg2TVHPNzCpVkpNk7kifCiwmw9VldkqYy9y/lCa" . "Epyp7lTfKw7cbD04Vk8QJW782L6Csuxkl346b17wmOqn8AZips3tFsuAY3w=\n" . "-----END CERTIFICATE-----\n" ; =pod The VICI interface requires a UNIX socket in order to communicate with the strongSwan charon daemon: use IO::Socket::UNIX; my $socket = IO::Socket::UNIX->new( Type => SOCK_STREAM, Peer => '/var/run/charon.vici', ) or die "Vici socket: $!"; =cut my $socket = IO::Socket::UNIX->new( Type => SOCK_STREAM, Peer => '/var/run/charon.vici', ) or die "Vici socket: $!"; =over =item new() creates a new Vici::Session object. use Vici::Session; use Vici::Message; my $session = Vici::Session->new($socket); =cut my $session = Vici::Session->new($socket); =item version() returns daemon and system specific version information. my $version = $session->version(); =cut print "----- version -----\n"; my $version = $session->version(); print $version->raw(), "\n"; =item load_cert() loads a certificate into the daemon. my %vars = ( type => 'X509', flag => 'CA', data => $ca_cert ); my ($res, $errmsg) = $session->load_cert(Vici::Message->new(\%vars)); =cut print "----- load-cert -----\n"; my %vars = ( type => 'X509', flag => 'CA', data => $ca_cert ); my ($res, $errmsg) = $session->load_cert(Vici::Message->new(\%vars)); print $res ? "ok\n" : "failed: $errmsg\n"; =item load_key() loads a private key into the daemon. my %vars = ( type => 'RSA', data => $moon_key ); my ($res, $errmsg) = $session->load_key(Vici::Message->new(\%vars)); =cut print "----- load-key -----\n"; %vars = ( type => 'RSA', data => $moon_key ); ($res, $errmsg) = $session->load_key(Vici::Message->new(\%vars)); print $res ? "ok\n" : "failed: $errmsg\n"; =item load_shared() loads a shared IKE PSK, EAP or XAuth secret into the daemon. my @owners = ( 'carol' ); my %vars = ( type => 'EAP', data => 'Ar3etTnp', owners => \@owners ); my ($res, $errmsg) = $session->load_shared(Vici::Message->new(\%vars)); =cut print "----- load-shared -----\n"; my @owners = ( 'carol' ); %vars = ( type => 'EAP', data => 'Ar3etTnp', owners => \@owners ); ($res, $errmsg) = $session->load_shared(Vici::Message->new(\%vars)); print $res ? "ok\n" : "failed: $errmsg\n"; =item load_authority() loads a single certification authority definition into the daemon. An existing authority with the same name gets replaced. my @crl_uris = ( 'http://crl.strongswan.org/strongswan.crl' ); my @ocsp_uris = ( 'http://ocsp.strongswan.org:8880' ); my %auth = ( cacert => $ca_cert, crl_uris => \@crl_uris, ocsp_uris => \@ocsp_uris ); my %vars = ( strongswan => \%auth ); my ($res, $errmsg) = $session->load_authority(Vici::Message->new(\%vars)); =cut print "----- load-authority -----\n"; my @crl_uris = ( 'http://crl.strongswan.org/strongswan.crl' ); my @ocsp_uris = ( 'http://ocsp.strongswan.org:8880' ); my %auth = ( cacert => $ca_cert, crl_uris => \@crl_uris, ocsp_uris => \@ocsp_uris ); %vars = ( strongswan => \%auth ); ($res, $errmsg) = $session->load_authority(Vici::Message->new(\%vars)); print $res ? "ok\n" : "failed: $errmsg\n"; =item load_conn() loads a single connection definition into the daemon. An existing connection with the same name gets updated or replaced. my @l_ts = ( '10.1.0.0/16' ); my @r_ts = ( '10.2.0.0/16' ); my @esp = ( 'aes128gcm128-modp3072' ); my %child = ( local_ts => \@l_ts, remote_ts => \@r_ts, esp_proposals => \@esp, ); my %children = ( 'net-net' => \%child ); my @l_addrs = ( '192.168.0.1' ); my @r_addrs = ( '192.168.0.2' ); my @l_certs = ( $moon_cert ); my %l = ( auth => 'pubkey', id => 'moon.strongswan.org', certs => \@l_certs ); my %r = ( auth => 'pubkey', id => 'sun.strongswan.org'); my @ike = ( 'aes128-sha256-modp3072' ); my %gw = ( version => 2, mobike => 'no', proposals => \@ike, local_addrs => \@l_addrs, remote_addrs => \@r_addrs, local => \%l, remote => \%r, children => \%children, ); my %vars = ( 'gw-gw' => \%gw); my ($res, $errmsg) = $session->load_conn(Vici::Message->new(\%vars)); =cut print "----- load-conn -----\n"; my @l_ts = ( '10.1.0.0/16' ); my @r_ts = ( '10.2.0.0/16' ); my @esp = ( 'aes128gcm128-modp3072' ); my %child = ( local_ts => \@l_ts, remote_ts => \@r_ts, esp_proposals => \@esp, ); my %children = ( 'net-net' => \%child ); my @l_addrs = ( '192.168.0.1' ); my @r_addrs = ( '192.168.0.2' ); my @l_certs = ( $moon_cert ); my %l = ( auth => 'pubkey', id => 'moon.strongswan.org', certs => \@l_certs ); my %r = ( auth => 'pubkey', id => 'sun.strongswan.org'); my @ike = ( 'aes128-sha256-modp3072' ); my %gw = ( version => 2, mobike => 'no', proposals => \@ike, local_addrs => \@l_addrs, remote_addrs => \@r_addrs, local => \%l, remote => \%r, children => \%children, ); %vars = ( 'gw-gw' => \%gw); ($res, $errmsg) = $session->load_conn(Vici::Message->new(\%vars)); print $res ? "ok\n" : "failed: $errmsg\n"; =item get_algorithms() lists all currently loaded algorithms and their implementation. my $algs = $session->get_algorithms(); =cut print "----- get-algorithms -----\n"; my $algs = $session->get_algorithms(); print $algs->raw(), "\n"; =item get_conns() returns a list of connection names loaded exclusively over VICI, not including connections found in other backends. my $conns = $session->get_conns(); =cut print "----- get-conns -----\n"; my $conns = $session->get_conns(); print $conns->raw(), "\n"; =item list_conns() lists currently loaded connections by streaming list-conn events. This call includes all connections known by the daemon, not only those loaded over VICI. my $conns = $session->list_conns(); foreach my $conn (@$conns) { print $conn->raw(), "\n"; } =cut print "----- list-conns -----\n"; $conns = $session->list_conns(); foreach my $conn (@$conns) { print $conn->raw(), "\n"; } =item initiate() initiates a CHILD_SA. my %vars = ( child => 'net-net' ); my($res, $errmsg) = $session->initiate(Vici::Message->new(\%vars)); =cut print "----- initiate -----\n"; %vars = ( child => 'net-net' ); ($res, $errmsg) = $session->initiate(Vici::Message->new(\%vars)); print $res ? "ok\n" : "failed: $errmsg\n"; =item list_sas() lists currently active IKE_SAs and associated CHILD_SAs by streaming list-sa events. my $sas = $session->list_sas(); foreach my $sa (@$sas) { print $sa->raw(), "\n"; } =cut print "----- list-sas -----\n"; my $sas = $session->list_sas(); foreach my $sa (@$sas) { print $sa->raw(), "\n"; } =item get_authorities() returns a list of currently loaded certification authority names. my $auths = $session->get_authorities(); =cut print "----- get-authorities -----\n"; my $auths = $session->get_authorities(); print $auths->raw(), "\n"; =item list-authorities() lists currently loaded certification authority information by streaming list-authority events. my $auths = $session->list_authorities(); foreach my $auth (@$auths) { print $auth->raw(), "\n"; } =cut print "----- list-authorities -----\n"; $auths = $session->list_authorities(); foreach my $auth (@$auths) { print $auth->raw(), "\n"; } =item list_certs() lists currently loaded certificates by streaming list-cert events. This call includes all certificates known by the daemon, not only those loaded over VICI. my %vars = ( subject => 'C=CH, O=Linux strongSwan, CN=moon.strongswan.org' ); my $certs = $session->list_certs(Vici::Message->new(\%vars)); =cut print "----- list-certs -----\n"; %vars = ( subject => 'C=CH, O=Linux strongSwan, CN=moon.strongswan.org' ); my $certs = $session->list_certs(Vici::Message->new(\%vars)); foreach my $cert (@$certs) { my $hash = $cert->hash(); print $hash->{'type'}, ": ", length($hash->{'data'}), ' bytes', $hash->{'has_privkey'} ? ', has private key' : '', "\n"; } =item stats() returns IKE daemon statistics and load information. my $stats = $session->stats(); =cut print "----- stats -----\n"; my $stats = $session->stats(); print $stats->raw(), "\n"; =item terminate() terminates an IKE_SA or CHILD_SA. my %vars = ( ike => 'gw-gw' ); my ($res, $errmsg) = $session->terminate(Vici::Message->new(\%vars)); =cut print "----- terminate -----\n"; %vars = ( ike => 'gw-gw' ); ($res, $errmsg) = $session->terminate(Vici::Message->new(\%vars)); print $res ? "ok\n" : "failed: $errmsg\n"; =item install() installs a trap, drop or bypass policy defined by a CHILD_SA config. my %vars = ( child => 'net-net' ); my ($res, $errmsg) = $session->install(Vici::Message->new(\%vars)); =cut print "----- install -----\n"; %vars = ( child => 'net-net' ); ($res, $errmsg) = $session->install(Vici::Message->new(\%vars)); print $res ? "ok\n" : "failed: $errmsg\n"; =item list_policies() lists currently installed trap, drop and bypass policies by streaming list-policy events. my %vars = ( trap => 'yes' ); my $pols = $session->list_policies(Vici::Message->new(\%vars)); foreach my $pol (@$pols) { print $pol->raw(), "\n"; } =cut print "----- list-policies -----\n"; %vars = ( trap => 'yes' ); my $pols = $session->list_policies(Vici::Message->new(\%vars)); foreach my $pol (@$pols) { print $pol->raw(), "\n"; } =item uninstall() uninstalls a trap, drop or bypass policy defined by a CHILD_SA config. my %vars = ( child => 'net-net' ); my ($res, $errmsg) = $session->uninstall(Vici::Message->new(\%vars)); =cut print "----- uninstall -----\n"; %vars = ( child => 'net-net' ); ($res, $errmsg) = $session->uninstall(Vici::Message->new(\%vars)); print $res ? "ok\n" : "failed: $errmsg\n"; =item reload_settings() reloads strongswan.conf settings and all plugins supporting configuration reload. my ($res, $errmsg) = $session->reload_settings(); print $res ? "ok\n" : "failed: $errmsg\n"; =cut print "----- reload-settings -----\n"; ($res, $errmsg) = $session->reload_settings(); print $res ? "ok\n" : "failed: $errmsg\n"; =item unload_conn() unloads a previously loaded connection definition by name. my %vars = ( name => 'gw-gw' ); my ($res, $errmsg) = $session->unload_conn(Vici::Message->new(\%vars)); =cut print "----- unload-conn -----\n"; %vars = ( name => 'gw-gw' ); ($res, $errmsg) = $session->unload_conn(Vici::Message->new(\%vars)); print $res ? "ok\n" : "failed: $errmsg\n"; =item unload_authority() unloads a previously loaded certification authority definition by name. my %vars = ( name => 'strongswan' ); my ($res, $errmsg) = $session->unload_authority(Vici::Message->new(\%vars)); =cut print "----- unload-authority -----\n"; %vars = ( name => 'strongswan' ); ($res, $errmsg) = $session->unload_authority(Vici::Message->new(\%vars)); print $res ? "ok\n" : "failed: $errmsg\n"; =item flush_certs() flushes the volatile certificate cache. Optionally only a given certificate type is flushed. my %vars = ( type => 'x509_crl' ); my ($res, $errmsg) = $session->flush_certs(Vici::Message->new(\%vars)); =cut print "----- flush-certs -----\n"; %vars = ( type => 'x509_crl' ); ($res, $errmsg) = $session->flush_certs(Vici::Message->new(\%vars)); print $res ? "ok\n" : "failed: $errmsg\n"; =item clear_creds() clears all loaded certificate, private key and shared key credentials. This affects only credentials loaded over vici, but additionally flushes the credential cache. my ($res, $errmsg) = $session->clear_creds(); =cut print "----- clear-creds -----\n"; ($res, $errmsg) = $session->clear_creds(); print $res ? "ok\n" : "failed: $errmsg\n"; =item load_pool() loads an in-memory virtual IP and configuration attribute pool. Existing pools with the same name get updated, if possible. my %pool = ( addrs => '10.3.0.0/23' ); my %vars = ( my_pool => \%pool ); my ($res, $errmsg) = $session->load_pool(Vici::Message->new(\%vars)); =cut print "----- load-pool -----\n"; my %pool = ( addrs => '10.3.0.0/23' ); %vars = ( my_pool => \%pool ); ($res, $errmsg) = $session->load_pool(Vici::Message->new(\%vars)); print $res ? "ok\n" : "failed: $errmsg\n"; =item get_pools() lists the currently loaded pools. my $pools = $session->get_pools(); =cut print "----- get-pools -----\n"; my $pools = $session->get_pools(); print $pools->raw(), "\n"; =item unload_pool() unloads a previously loaded virtual IP and configuration attribute pool. Unloading fails for pools with leases currently online. my %vars = ( name => 'my_pool' ); my ($res, $errmsg) = $session->unload_pool(Vici::Message->new(\%vars)); =cut print "----- unload-pool -----\n"; %vars = ( name => 'my_pool' ); ($res, $errmsg) = $session->unload_pool(Vici::Message->new(\%vars)); print $res ? "ok\n" : "failed: $errmsg\n"; =back =cut # close vici socket close($socket); =head1 COPYRIGHT AND LICENSE Copyright (c) 2015 Andreas Steffen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.