├── .gitattributes ├── .gitorderfile ├── .gitmodules ├── .gitignore ├── rpc ├── rpc.cc └── rpc_types.hh ├── licenses ├── dpdk.txt └── freebsd.txt ├── kvm ├── register.sh ├── build.sh ├── scripts │ └── bootstrap.sh └── README.md ├── docker └── dev │ └── Dockerfile ├── NOTICE ├── http ├── mime_types.hh ├── api_docs.cc ├── common.cc ├── mime_types.cc ├── transformers.cc ├── transformers.hh ├── common.hh ├── handlers.hh ├── json_path.cc ├── matcher.cc ├── httpd.cc ├── matcher.hh ├── http_response_parser.rl └── request.hh ├── core ├── distributed.hh ├── units.hh ├── scollectd_api.hh ├── enum.hh ├── vector-data-sink.hh ├── task.hh ├── sleep.hh ├── bitops.hh ├── array_map.hh ├── resource.hh ├── align.hh ├── vla.hh ├── shared_ptr_debug_helper.hh ├── xen │ ├── evtchn.hh │ ├── osv_xen.hh │ ├── gntalloc.hh │ ├── xenstore.cc │ └── xenstore.hh ├── dpdk_rte.hh ├── apply.hh ├── function_traits.hh ├── app-template.hh ├── timer.hh ├── transfer.hh ├── unaligned.hh ├── fstream.hh ├── scattered_message.hh └── gate.hh ├── apps ├── seastar │ └── main.cc ├── memcached │ └── memcached.hh └── httpd │ ├── demo.json │ └── main.cc ├── net ├── proxy.hh ├── native-stack.hh ├── virtio.hh ├── const.hh ├── tcp-stack.hh ├── dpdk.hh ├── ethernet.cc ├── packet-data-source.hh ├── udp.hh ├── ip_checksum.hh ├── ethernet.hh ├── ip_checksum.cc ├── proxy.cc ├── dhcp.hh └── arp.cc ├── util ├── is_smart_ptr.hh ├── eclipse.hh ├── defer.hh ├── conversions.cc ├── conversions.hh ├── transform_iterator.hh └── function_input_iterator.hh ├── scripts ├── tap.sh └── run_with_dpdk.sh ├── README-DPDK.md ├── tests ├── foreign_ptr_test.cc ├── alloc_test.cc ├── test_runner.hh ├── ip_test.cc ├── test-utils.hh ├── l3_test.cc ├── memcached │ └── test.py ├── directory_test.cc ├── packet_test.cc ├── blkdiscard_test.cc ├── exchanger.hh ├── tcp_test.cc ├── test-utils.cc ├── smp_test.cc ├── udp_server.cc ├── udp_client.cc ├── fileiotest.cc ├── linecount.cc ├── test_runner.cc ├── thread_context_switch.cc ├── timertest.cc └── shared_ptr_test.cc ├── json ├── formatter.cc └── json_elements.cc └── doc ├── template.tex └── template.css /.gitattributes: -------------------------------------------------------------------------------- 1 | *.cc diff=cpp 2 | *.hh diff=cpp 3 | -------------------------------------------------------------------------------- /.gitorderfile: -------------------------------------------------------------------------------- 1 | *.py 2 | *.hh 3 | *.rl 4 | *.cc 5 | * 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "dpdk"] 2 | path = dpdk 3 | url = ../dpdk 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .cproject 2 | .project 3 | .settings 4 | build 5 | build.ninja 6 | cscope.* 7 | -------------------------------------------------------------------------------- /rpc/rpc.cc: -------------------------------------------------------------------------------- 1 | #include "rpc.hh" 2 | 3 | namespace rpc { 4 | no_wait_type no_wait; 5 | } 6 | -------------------------------------------------------------------------------- /licenses/dpdk.txt: -------------------------------------------------------------------------------- 1 | This project contains files from DPDK project that are distributed under BSD license. 2 | -------------------------------------------------------------------------------- /kvm/register.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | virt-install --import --noreboot --name seastar-dev --vcpus 4 --ram 4096 --disk path=`realpath seastar-dev.qcow2`,format=qcow2,bus=virtio --accelerate --network=network:default,model=virtio --serial pty --cpu host --rng=/dev/random 4 | -------------------------------------------------------------------------------- /kvm/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rm -rf /tmp/seastar 4 | cp -a ../ /tmp/seastar 5 | virt-builder fedora-21 -o seastar-dev.qcow2 --format qcow2 --size 20G --hostname seastar-dev --install "@core" --update --selinux-relabel --copy-in /tmp/seastar:/root/ --firstboot scripts/bootstrap.sh 6 | rm -rf /tmp/seastar 7 | -------------------------------------------------------------------------------- /docker/dev/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fedora:21 2 | 3 | RUN yum install -y gcc-c++ clang libasan libubsan hwloc hwloc-devel numactl-devel \ 4 | python3 libaio-devel ninja-build boost-devel git ragel xen-devel \ 5 | cryptopp-devel libpciaccess-devel libxml2-devel zlib-devel 6 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Seastar Framework 2 | Copyright 2015 Cloudius Systems 3 | 4 | This works contains software from the OSv project (http://osv.io), licensed 5 | under the BSD license. 6 | 7 | This work contains software from the DPDK project (http://dpdk.org), licensed 8 | under the BSD license. The software is under the dpdk/ directory. 9 | -------------------------------------------------------------------------------- /http/mime_types.hh: -------------------------------------------------------------------------------- 1 | // 2 | // mime_types.hpp 3 | // ~~~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | 11 | #ifndef HTTP_MIME_TYPES_HH 12 | #define HTTP_MIME_TYPES_HH 13 | 14 | #include "core/sstring.hh" 15 | 16 | namespace httpd { 17 | 18 | namespace mime_types { 19 | 20 | /** 21 | * Convert a file extension into a MIME type. 22 | * 23 | * @param extension the file extension 24 | * @return the mime type as a string 25 | */ 26 | const char* extension_to_type(const sstring& extension); 27 | 28 | } // namespace mime_types 29 | 30 | } // namespace httpd 31 | 32 | #endif // HTTP_MIME_TYPES_HH 33 | -------------------------------------------------------------------------------- /kvm/scripts/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | nmcli c modify eth0 ipv4.ignore-auto-dns "yes" 3 | systemctl restart network 4 | echo nameserver 8.8.8.8 > /etc/resolv.conf 5 | useradd -m -p "" -g wheel seastar 6 | chage -d 0 seastar 7 | yum install -y gcc gcc-c++ libaio-devel ninja-build ragel hwloc-devel numactl-devel libpciaccess-devel cryptopp-devel xen-devel boost-devel kernel-devel libxml2-devel zlib-devel libasan libubsan git wget python3 tar pciutils xterm 8 | cd /root 9 | wget http://dpdk.org/browse/dpdk/snapshot/dpdk-2.0.0.tar.gz 10 | tar -xpf dpdk-2.0.0.tar.gz 11 | mv dpdk-2.0.0 dpdk 12 | cd dpdk 13 | cat config/common_linuxapp | sed -e "s/CONFIG_RTE_MBUF_REFCNT_ATOMIC=y/CONFIG_RTE_MBUF_REFCNT_ATOMIC=n/g" | sed -e "s/CONFIG_RTE_BUILD_SHARED_LIB=n/CONFIG_RTE_BUILD_SHARED_LIB=y/g" > /tmp/common_linuxapp 14 | mv /tmp/common_linuxapp config 15 | make T=x86_64-native-linuxapp-gcc install 16 | cd - 17 | cd seastar 18 | ./configure.py --dpdk-target ~/dpdk/x86_64-native-linuxapp-gcc --disable-xen 19 | ninja-build -j2 20 | -------------------------------------------------------------------------------- /core/distributed.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #pragma once 23 | 24 | #include "sharded.hh" 25 | 26 | template 27 | using distributed = seastar::sharded; 28 | -------------------------------------------------------------------------------- /apps/seastar/main.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2014 Cloudius Systems 20 | */ 21 | 22 | 23 | #include "core/reactor.hh" 24 | 25 | int main(int ac, char** av) 26 | { 27 | reactor r; 28 | r.run(); 29 | return 0; 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /net/proxy.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | #ifndef PROXY_HH_ 19 | #define PROXY_HH_ 20 | 21 | #include 22 | #include "net.hh" 23 | #include "packet.hh" 24 | 25 | namespace net { 26 | 27 | std::unique_ptr create_proxy_net_device(unsigned master_cpu, device* dev); 28 | 29 | } 30 | #endif 31 | -------------------------------------------------------------------------------- /core/units.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef UNITS_HH_ 23 | #define UNITS_HH_ 24 | 25 | static constexpr size_t KB = 1 << 10; 26 | static constexpr size_t MB = 1 << 20; 27 | static constexpr size_t GB = 1 << 30; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /util/is_smart_ptr.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #pragma once 23 | 24 | #include // for std::unique_ptr 25 | 26 | template 27 | struct is_smart_ptr : std::false_type {}; 28 | 29 | template 30 | struct is_smart_ptr> : std::true_type {}; 31 | -------------------------------------------------------------------------------- /net/native-stack.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef STACK_HH_ 23 | #define STACK_HH_ 24 | 25 | #include "net/net.hh" 26 | #include 27 | 28 | namespace net { 29 | 30 | void create_native_stack(boost::program_options::variables_map opts, std::shared_ptr dev); 31 | 32 | } 33 | 34 | #endif /* STACK_HH_ */ 35 | -------------------------------------------------------------------------------- /http/api_docs.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #include "api_docs.hh" 23 | #include "handlers.hh" 24 | #include "json/formatter.hh" 25 | #include "transformers.hh" 26 | 27 | using namespace std; 28 | 29 | namespace httpd { 30 | 31 | const sstring api_registry_builder::DEFAULT_PATH = "/api-doc"; 32 | const sstring api_registry_builder::DEFAULT_DIR = "."; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /scripts/tap.sh: -------------------------------------------------------------------------------- 1 | # 2 | # This file is open source software, licensed to you under the terms 3 | # of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | # distributed with this work for additional information regarding copyright 5 | # ownership. You may not use this file except in compliance with the License. 6 | # 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | # 18 | 19 | ### Set up a tap device for seastar 20 | tap=tap0 21 | bridge=virbr0 22 | user=`whoami` 23 | sudo tunctl -d $tap 24 | sudo ip tuntap add mode tap dev $tap user $user one_queue vnet_hdr 25 | sudo ifconfig $tap up 26 | sudo brctl addif $bridge $tap 27 | sudo brctl stp $bridge off 28 | sudo modprobe vhost-net 29 | sudo chown $user.$user /dev/vhost-net 30 | sudo brctl show $bridge 31 | sudo ifconfig $bridge 32 | -------------------------------------------------------------------------------- /http/common.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #include "common.hh" 23 | 24 | namespace httpd { 25 | 26 | operation_type str2type(const sstring& type) { 27 | if (type == "DELETE") { 28 | return DELETE; 29 | } 30 | if (type == "POST") { 31 | return POST; 32 | } 33 | if (type == "PUT") { 34 | return PUT; 35 | } 36 | return GET; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /README-DPDK.md: -------------------------------------------------------------------------------- 1 | Seastar and DPDK 2 | ================ 3 | 4 | Seastar uses the Data Plane Development Kit to drive NIC hardware directly. This 5 | provides an enormous performance boost. 6 | 7 | To enable DPDK, specify `--enable-dpdk` to `./configure.py`, and `--dpdk-pmd` as a 8 | run-time parameter. This will use the DPDK package provided as a git submodule with the 9 | seastar sources. 10 | 11 | To use your own self-compiled DPDK package, follow this procedure: 12 | 13 | 1. Setup host to compile DPDK: 14 | - Ubuntu 15 | `sudo apt-get install -y build-essential linux-image-extra-$(uname -r)` 16 | 2. Prepare a DPDK SDK: 17 | - Download the latest DPDK release: `wget http://dpdk.org/browse/dpdk/snapshot/dpdk-2.0.0.tar.gz` 18 | - Untar it. 19 | - Edit config/common_linuxapp: set CONFIG_RTE_MBUF_REFCNT_ATOMIC and CONFIG_RTE_LIBRTE_KNI to 'n'. 20 | - Start the tools/setup.sh script as root. 21 | - Compile a linuxapp target (option 9). 22 | - Install IGB_UIO module (option 12). 23 | - Bind some physical port to IGB_UIO (option 18). 24 | - Configure hugepage mappings (option 15/16). 25 | 3. Run a configure.py: `./configure.py --dpdk-target /x86_64-native-linuxapp-gcc`. 26 | -------------------------------------------------------------------------------- /http/mime_types.cc: -------------------------------------------------------------------------------- 1 | // 2 | // mime_types.cpp 3 | // ~~~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | 11 | #include "mime_types.hh" 12 | 13 | namespace httpd { 14 | namespace mime_types { 15 | 16 | struct mapping { 17 | const char* extension; 18 | const char* mime_type; 19 | } mappings[] = { 20 | { "gif", "image/gif" }, 21 | { "htm", "text/html" }, 22 | { "css", "text/css" }, 23 | { "js", "text/javascript" }, 24 | { "html", "text/html" }, 25 | { "jpg", "image/jpeg" }, 26 | { "png", "image/png" }, 27 | { "txt", "text/plain" }, 28 | { "ico", "image/x-icon" }, 29 | { "bin", "application/octet-stream" }, 30 | }; 31 | 32 | const char* extension_to_type(const sstring& extension) 33 | { 34 | for (mapping m : mappings) { 35 | if (extension == m.extension) { 36 | return m.mime_type; 37 | } 38 | } 39 | return "text/plain"; 40 | } 41 | 42 | } // namespace mime_types 43 | 44 | } // httpd 45 | -------------------------------------------------------------------------------- /util/eclipse.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | * 21 | */ 22 | 23 | #ifndef ECLIPSE_HH_ 24 | #define ECLIPSE_HH_ 25 | 26 | // Workarounds for deficiencies in Eclipse's C++ parser 27 | // 28 | // Tell Eclipse that IN_ECLIPSE is defined so it will ignore all the unknown syntax. 29 | 30 | #ifndef IN_ECLIPSE 31 | 32 | #else 33 | 34 | // Eclipse doesn't grok alignof 35 | #define alignof sizeof 36 | 37 | #endif 38 | 39 | #endif /* ECLIPSE_HH_ */ 40 | -------------------------------------------------------------------------------- /net/virtio.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef VIRTIO_HH_ 23 | #define VIRTIO_HH_ 24 | 25 | #include 26 | #include "net.hh" 27 | #include "core/sstring.hh" 28 | 29 | std::unique_ptr create_virtio_net_device(boost::program_options::variables_map opts = boost::program_options::variables_map()); 30 | boost::program_options::options_description get_virtio_net_options_description(); 31 | 32 | #endif /* VIRTIO_HH_ */ 33 | -------------------------------------------------------------------------------- /licenses/freebsd.txt: -------------------------------------------------------------------------------- 1 | Redistribution and use in source and binary forms, with or without 2 | modification, are permitted provided that the following conditions 3 | are met: 4 | 1. Redistributions of source code must retain the above copyright 5 | notice, this list of conditions and the following disclaimer. 6 | 2. Redistributions in binary form must reproduce the above copyright 7 | notice, this list of conditions and the following disclaimer in the 8 | documentation and/or other materials provided with the distribution. 9 | 10 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 11 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 12 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 13 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 14 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 15 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 16 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 17 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 19 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 20 | SUCH DAMAGE. 21 | -------------------------------------------------------------------------------- /net/const.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef CONST_HH_ 23 | #define CONST_HH_ 24 | namespace net { 25 | 26 | enum class ip_protocol_num : uint8_t { 27 | icmp = 1, tcp = 6, udp = 17, unused = 255 28 | }; 29 | 30 | enum class eth_protocol_num : uint16_t { 31 | ipv4 = 0x0800, arp = 0x0806, ipv6 = 0x86dd 32 | }; 33 | 34 | const uint8_t eth_hdr_len = 14; 35 | const uint8_t tcp_hdr_len_min = 20; 36 | const uint8_t ipv4_hdr_len_min = 20; 37 | const uint8_t ipv6_hdr_len_min = 40; 38 | const uint16_t ip_packet_len_max = 65535; 39 | 40 | } 41 | #endif 42 | -------------------------------------------------------------------------------- /tests/foreign_ptr_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include "tests/test-utils.hh" 23 | 24 | #include "core/distributed.hh" 25 | #include "core/shared_ptr.hh" 26 | 27 | SEASTAR_TEST_CASE(make_foreign_ptr_from_lw_shared_ptr) { 28 | auto p = make_foreign(make_lw_shared("foo")); 29 | BOOST_REQUIRE(p->size() == 3); 30 | return make_ready_future<>(); 31 | } 32 | 33 | SEASTAR_TEST_CASE(make_foreign_ptr_from_shared_ptr) { 34 | auto p = make_foreign(make_shared("foo")); 35 | BOOST_REQUIRE(p->size() == 3); 36 | return make_ready_future<>(); 37 | } 38 | -------------------------------------------------------------------------------- /util/defer.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef UTIL_DEFER_HH_ 23 | #define UTIL_DEFER_HH_ 24 | 25 | template 26 | class deferred_action { 27 | Func _func; 28 | bool _cancelled = false; 29 | public: 30 | deferred_action(Func&& func) : _func(std::move(func)) {} 31 | ~deferred_action() { _func(); } 32 | void cancel() { _cancelled = true; } 33 | }; 34 | 35 | template 36 | inline 37 | deferred_action 38 | defer(Func&& func) { 39 | return deferred_action(std::forward(func)); 40 | } 41 | 42 | #endif /* UTIL_DEFER_HH_ */ 43 | -------------------------------------------------------------------------------- /net/tcp-stack.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | // tcp/network-stack integration 23 | 24 | #ifndef NET_TCP_STACK_HH 25 | #define NET_TCP_STACK_HH 26 | 27 | #include "core/future.hh" 28 | 29 | class listen_options; 30 | class server_socket; 31 | class connected_socket; 32 | 33 | namespace net { 34 | 35 | class ipv4_traits; 36 | template 37 | class tcp; 38 | 39 | server_socket 40 | tcpv4_listen(tcp& tcpv4, uint16_t port, listen_options opts); 41 | 42 | future 43 | tcpv4_connect(tcp& tcpv4, socket_address sa); 44 | 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /tests/alloc_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include "tests/test-utils.hh" 23 | #include "core/memory.hh" 24 | 25 | 26 | SEASTAR_TEST_CASE(alloc_almost_all_and_realloc_it_with_a_smaller_size) { 27 | #ifndef DEFAULT_ALLOCATOR 28 | auto all = memory::stats().total_memory(); 29 | auto reserve = size_t(0.02 * all); 30 | auto to_alloc = all - (reserve + (10 << 20)); 31 | auto obj = malloc(to_alloc); 32 | BOOST_REQUIRE(obj != nullptr); 33 | auto obj2 = realloc(obj, to_alloc - (1 << 20)); 34 | BOOST_REQUIRE(obj == obj2); 35 | free(obj2); 36 | #endif 37 | return make_ready_future<>(); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /http/transformers.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #include 23 | #include "transformers.hh" 24 | #include 25 | 26 | namespace httpd { 27 | 28 | using namespace std; 29 | 30 | void content_replace::transform(sstring& content, const request& req, 31 | const sstring& extension) { 32 | sstring host = req.get_header("Host"); 33 | if (host == "" || (this->extension != "" && extension != this->extension)) { 34 | return; 35 | } 36 | boost::replace_all(content, "{{Host}}", host); 37 | boost::replace_all(content, "{{Protocol}}", req.get_protocol_name()); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /core/scollectd_api.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Cloudius Systems 3 | */ 4 | 5 | #ifndef CORE_SCOLLECTD_API_HH_ 6 | #define CORE_SCOLLECTD_API_HH_ 7 | 8 | #include "core/scollectd.hh" 9 | 10 | namespace scollectd { 11 | 12 | struct collectd_value { 13 | union { 14 | double _d; 15 | uint64_t _ui; 16 | int64_t _i; 17 | } u; 18 | scollectd::data_type _type; 19 | collectd_value() 20 | : _type(data_type::GAUGE) { 21 | } 22 | collectd_value(data_type t, uint64_t i) 23 | : _type(t) { 24 | u._ui = i; 25 | } 26 | 27 | collectd_value& operator=(const collectd_value& c) = default; 28 | 29 | collectd_value& operator+=(const collectd_value& c) { 30 | *this = *this + c; 31 | return *this; 32 | } 33 | 34 | collectd_value operator+(const collectd_value& c) { 35 | collectd_value res(*this); 36 | switch (_type) { 37 | case data_type::GAUGE: 38 | res.u._d += c.u._d; 39 | break; 40 | case data_type::DERIVE: 41 | res.u._i += c.u._i; 42 | break; 43 | default: 44 | res.u._ui += c.u._ui; 45 | break; 46 | } 47 | return res; 48 | } 49 | }; 50 | 51 | std::vector get_collectd_value( 52 | const scollectd::type_instance_id& id); 53 | 54 | std::vector get_collectd_ids(); 55 | 56 | } 57 | 58 | #endif /* CORE_SCOLLECTD_API_HH_ */ 59 | -------------------------------------------------------------------------------- /tests/test_runner.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include 27 | #include "core/future.hh" 28 | #include "core/posix.hh" 29 | #include "exchanger.hh" 30 | 31 | class posix_thread; 32 | 33 | class test_runner { 34 | private: 35 | std::unique_ptr _thread; 36 | std::atomic _started{false}; 37 | exchanger()>> _task; 38 | bool _done = false; 39 | public: 40 | void start(int argc, char** argv); 41 | ~test_runner(); 42 | void run_sync(std::function()> task); 43 | }; 44 | 45 | test_runner& global_test_runner(); 46 | -------------------------------------------------------------------------------- /core/enum.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #pragma once 23 | 24 | /* 25 | * This header file defines a hash function for enum types, using the 26 | * standard hash function of the underlying type (such as int). This makes 27 | * it possible to inherit from this type to 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | template 35 | class enum_hash { 36 | static_assert(std::is_enum::value, "must be an enum"); 37 | public: 38 | std::size_t operator()(const T& e) const { 39 | using utype = typename std::underlying_type::type; 40 | return std::hash()(static_cast(e)); 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /core/vector-data-sink.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2014 Cloudius Systems 20 | */ 21 | 22 | #ifndef VECTOR_DATA_SINK_HH_ 23 | #define VECTOR_DATA_SINK_HH_ 24 | 25 | #include "core/reactor.hh" 26 | 27 | class vector_data_sink final : public data_sink_impl { 28 | public: 29 | using vector_type = std::vector; 30 | private: 31 | vector_type& _v; 32 | public: 33 | vector_data_sink(vector_type& v) : _v(v) {} 34 | 35 | virtual future<> put(net::packet p) override { 36 | _v.push_back(std::move(p)); 37 | return make_ready_future<>(); 38 | } 39 | 40 | virtual future<> close() override { 41 | // TODO: close on local side 42 | return make_ready_future<>(); 43 | } 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /core/task.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | class task { 27 | public: 28 | virtual ~task() noexcept {} 29 | virtual void run() noexcept = 0; 30 | }; 31 | 32 | void schedule(std::unique_ptr t); 33 | 34 | template 35 | class lambda_task final : public task { 36 | Func _func; 37 | public: 38 | lambda_task(const Func& func) : _func(func) {} 39 | lambda_task(Func&& func) : _func(std::move(func)) {} 40 | virtual void run() noexcept override { _func(); } 41 | }; 42 | 43 | template 44 | inline 45 | std::unique_ptr 46 | make_task(Func&& func) { 47 | return std::make_unique>(std::forward(func)); 48 | } 49 | -------------------------------------------------------------------------------- /tests/ip_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include "net/arp.hh" 23 | #include "net/ip.hh" 24 | #include "net/net.hh" 25 | #include "core/reactor.hh" 26 | #include "net/virtio.hh" 27 | 28 | using namespace net; 29 | 30 | int main(int ac, char** av) { 31 | boost::program_options::variables_map opts; 32 | opts.insert(std::make_pair("tap-device", boost::program_options::variable_value(std::string("tap0"), false))); 33 | 34 | auto vnet = create_virtio_net_device(opts); 35 | vnet->set_local_queue(vnet->init_local_queue(opts, 0)); 36 | 37 | interface netif(std::move(vnet)); 38 | ipv4 inet(&netif); 39 | inet.set_host_address(ipv4_address("192.168.122.2")); 40 | engine().run(); 41 | return 0; 42 | } 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /util/conversions.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef CONVERSIONS_CC_ 23 | #define CONVERSIONS_CC_ 24 | 25 | #include "conversions.hh" 26 | #include "core/print.hh" 27 | #include 28 | 29 | size_t parse_memory_size(std::string s) { 30 | size_t factor = 1; 31 | if (s.size()) { 32 | auto c = s[s.size() - 1]; 33 | static std::string suffixes = "kMGT"; 34 | auto pos = suffixes.find(c); 35 | if (pos == suffixes.npos) { 36 | throw std::runtime_error(sprint("Cannot parse memory size '%s'", s)); 37 | } 38 | factor <<= (pos + 1) * 10; 39 | s = s.substr(0, s.size() - 1); 40 | } 41 | return boost::lexical_cast(s) * factor; 42 | } 43 | 44 | 45 | #endif /* CONVERSIONS_CC_ */ 46 | -------------------------------------------------------------------------------- /util/conversions.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef CONVERSIONS_HH_ 23 | #define CONVERSIONS_HH_ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | // Convert a string to a memory size, allowing binary SI 30 | // suffixes (intentionally, even though SI suffixes are 31 | // decimal, to follow existing usage). 32 | // 33 | // "5" -> 5 34 | // "4k" -> (4 << 10) 35 | // "8M" -> (8 << 20) 36 | // "7G" -> (7 << 30) 37 | // "1T" -> (1 << 40) 38 | // anything else: exception 39 | size_t parse_memory_size(std::string s); 40 | 41 | static inline std::vector string2vector(std::string str) { 42 | auto v = std::vector(str.begin(), str.end()); 43 | v.push_back('\0'); 44 | return v; 45 | } 46 | 47 | #endif /* CONVERSIONS_HH_ */ 48 | -------------------------------------------------------------------------------- /core/sleep.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | /* 20 | * Copyright (C) 2015 Cloudius Systems, Ltd. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | #include 27 | 28 | #include "core/shared_ptr.hh" 29 | #include "core/reactor.hh" 30 | #include "core/future.hh" 31 | 32 | template 33 | future<> sleep(std::chrono::duration dur) { 34 | struct sleeper { 35 | promise<> done; 36 | timer tmr; 37 | sleeper(std::chrono::duration dur) 38 | : tmr([this] { done.set_value(); }) 39 | { 40 | tmr.arm(dur); 41 | } 42 | }; 43 | sleeper *s = new sleeper(dur); 44 | future<> fut = s->done.get_future(); 45 | return fut.then([s] { delete s; }); 46 | } 47 | -------------------------------------------------------------------------------- /core/bitops.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef BITOPS_HH_ 23 | #define BITOPS_HH_ 24 | 25 | inline 26 | constexpr unsigned count_leading_zeros(unsigned x) { 27 | return __builtin_clz(x); 28 | } 29 | 30 | inline 31 | constexpr unsigned count_leading_zeros(unsigned long x) { 32 | return __builtin_clzl(x); 33 | } 34 | 35 | inline 36 | constexpr unsigned count_leading_zeros(unsigned long long x) { 37 | return __builtin_clzll(x); 38 | } 39 | 40 | inline 41 | constexpr unsigned count_trailing_zeros(unsigned x) { 42 | return __builtin_ctz(x); 43 | } 44 | 45 | inline 46 | constexpr unsigned count_trailing_zeros(unsigned long x) { 47 | return __builtin_ctzl(x); 48 | } 49 | 50 | inline 51 | constexpr unsigned count_trailing_zeros(unsigned long long x) { 52 | return __builtin_ctzll(x); 53 | } 54 | 55 | #endif /* BITOPS_HH_ */ 56 | -------------------------------------------------------------------------------- /net/dpdk.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifdef HAVE_DPDK 23 | 24 | #ifndef _SEASTAR_DPDK_DEV_H 25 | #define _SEASTAR_DPDK_DEV_H 26 | 27 | #include 28 | #include "net.hh" 29 | #include "core/sstring.hh" 30 | 31 | std::unique_ptr create_dpdk_net_device( 32 | uint8_t port_idx = 0, 33 | uint8_t num_queues = 1, 34 | bool use_lro = true, 35 | bool enable_fc = true); 36 | 37 | boost::program_options::options_description get_dpdk_net_options_description(); 38 | 39 | namespace dpdk { 40 | /** 41 | * @return Number of bytes needed for mempool objects of each QP. 42 | */ 43 | uint32_t qp_mempool_obj_size(bool hugetlbfs_membackend); 44 | } 45 | 46 | #endif // _SEASTAR_DPDK_DEV_H 47 | 48 | #endif // HAVE_DPDK 49 | -------------------------------------------------------------------------------- /tests/test-utils.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | /* 20 | * Copyright (C) 2014 Cloudius Systems, Ltd. 21 | */ 22 | 23 | #pragma once 24 | 25 | #define BOOST_TEST_DYN_LINK 26 | 27 | #include 28 | 29 | #include "core/future.hh" 30 | #include "test_runner.hh" 31 | 32 | class seastar_test { 33 | public: 34 | seastar_test(); 35 | virtual ~seastar_test() {} 36 | virtual const char* get_test_file() = 0; 37 | virtual const char* get_name() = 0; 38 | virtual future<> run_test_case() = 0; 39 | void run(); 40 | }; 41 | 42 | #define SEASTAR_TEST_CASE(name) \ 43 | struct name : public seastar_test { \ 44 | const char* get_test_file() override { return __FILE__; } \ 45 | const char* get_name() override { return #name; } \ 46 | future<> run_test_case() override; \ 47 | }; \ 48 | static name name ## _instance; \ 49 | future<> name::run_test_case() 50 | 51 | -------------------------------------------------------------------------------- /core/array_map.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef ARRAY_MAP_HH_ 23 | #define ARRAY_MAP_HH_ 24 | 25 | #include 26 | 27 | // unordered_map implemented as a simple array 28 | 29 | template 30 | class array_map { 31 | std::array _a {}; 32 | public: 33 | array_map(std::initializer_list> i) { 34 | for (auto kv : i) { 35 | _a[kv.first] = kv.second; 36 | } 37 | } 38 | Value& operator[](size_t key) { return _a[key]; } 39 | const Value& operator[](size_t key) const { return _a[key]; } 40 | 41 | Value& at(size_t key) { 42 | if (key >= Max) { 43 | throw std::out_of_range(std::to_string(key) + " >= " + std::to_string(Max)); 44 | } 45 | return _a[key]; 46 | } 47 | }; 48 | 49 | 50 | 51 | #endif /* ARRAY_MAP_HH_ */ 52 | -------------------------------------------------------------------------------- /net/ethernet.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include "ethernet.hh" 23 | #include 24 | #include 25 | 26 | namespace net { 27 | 28 | std::ostream& operator<<(std::ostream& os, ethernet_address ea) { 29 | auto& m = ea.mac; 30 | using u = uint32_t; 31 | return fprint(os, "%02x:%02x:%02x:%02x:%02x:%02x", 32 | u(m[0]), u(m[1]), u(m[2]), u(m[3]), u(m[4]), u(m[5])); 33 | } 34 | 35 | ethernet_address parse_ethernet_address(std::string addr) 36 | { 37 | std::vector v; 38 | boost::split(v, addr , boost::algorithm::is_any_of(":")); 39 | 40 | if (v.size() != 6) { 41 | throw std::runtime_error("invalid mac address\n"); 42 | } 43 | 44 | ethernet_address a; 45 | unsigned i = 0; 46 | for (auto &x: v) { 47 | a.mac[i++] = std::stoi(x, nullptr,16); 48 | } 49 | return a; 50 | } 51 | } 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /core/resource.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef RESOURCE_HH_ 23 | #define RESOURCE_HH_ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | cpu_set_t cpuid_to_cpuset(unsigned cpuid); 31 | 32 | namespace resource { 33 | 34 | using std::experimental::optional; 35 | 36 | using cpuset = std::set; 37 | 38 | struct configuration { 39 | optional total_memory; 40 | optional reserve_memory; // if total_memory not specified 41 | optional cpus; 42 | optional cpu_set; 43 | }; 44 | 45 | struct memory { 46 | size_t bytes; 47 | unsigned nodeid; 48 | 49 | }; 50 | 51 | struct cpu { 52 | unsigned cpu_id; 53 | std::vector mem; 54 | }; 55 | 56 | std::vector allocate(configuration c); 57 | unsigned nr_processing_units(); 58 | 59 | } 60 | 61 | #endif /* RESOURCE_HH_ */ 62 | -------------------------------------------------------------------------------- /core/align.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef ALIGN_HH_ 23 | #define ALIGN_HH_ 24 | 25 | #include 26 | #include 27 | 28 | template 29 | inline constexpr 30 | T align_up(T v, T align) { 31 | return (v + align - 1) & ~(align - 1); 32 | } 33 | 34 | template 35 | inline constexpr 36 | T* align_up(T* v, size_t align) { 37 | static_assert(sizeof(T) == 1, "align byte pointers only"); 38 | return reinterpret_cast(align_up(reinterpret_cast(v), align)); 39 | } 40 | 41 | template 42 | inline constexpr 43 | T align_down(T v, T align) { 44 | return v & ~(align - 1); 45 | } 46 | 47 | template 48 | inline constexpr 49 | T* align_down(T* v, size_t align) { 50 | static_assert(sizeof(T) == 1, "align byte pointers only"); 51 | return reinterpret_cast(align_down(reinterpret_cast(v), align)); 52 | } 53 | 54 | #endif /* ALIGN_HH_ */ 55 | -------------------------------------------------------------------------------- /tests/l3_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include "net/net.hh" 23 | #include "core/reactor.hh" 24 | #include "net/virtio.hh" 25 | 26 | using namespace net; 27 | 28 | void dump_arp_packets(l3_protocol& proto) { 29 | proto.receive([&proto] (packet p, ethernet_address from) { 30 | std::cout << "seen arp packet\n"; 31 | return make_ready_future<>(); 32 | }, [] (forward_hash& out_hash_data, packet& p, size_t off) {return false;}); 33 | } 34 | 35 | int main(int ac, char** av) { 36 | boost::program_options::variables_map opts; 37 | opts.insert(std::make_pair("tap-device", boost::program_options::variable_value(std::string("tap0"), false))); 38 | 39 | auto vnet = create_virtio_net_device(opts); 40 | interface netif(std::move(vnet)); 41 | l3_protocol arp(&netif, eth_protocol_num::arp, []{ return std::experimental::optional(); }); 42 | dump_arp_packets(arp); 43 | engine().run(); 44 | return 0; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /core/vla.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef VLA_HH_ 23 | #define VLA_HH_ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | // Some C APIs have a structure with a variable length array at the end. 31 | // This is a helper function to help allocate it. 32 | // 33 | // for a structure 34 | // 35 | // struct xx { int a; float b[0]; }; 36 | // 37 | // use 38 | // 39 | // make_struct_with_vla(&xx::b, number_of_bs); 40 | // 41 | // to allocate it. 42 | // 43 | template 44 | inline 45 | std::unique_ptr 46 | make_struct_with_vla(E S::*last, size_t nr) { 47 | auto fake = reinterpret_cast(0); 48 | size_t offset = reinterpret_cast(&(fake->*last)); 49 | size_t element_size = sizeof((fake->*last)[0]); 50 | assert(offset == sizeof(S)); 51 | auto p = ::operator new(offset + element_size * nr); 52 | return std::unique_ptr(new (p) S()); 53 | } 54 | 55 | 56 | 57 | #endif /* VLA_HH_ */ 58 | -------------------------------------------------------------------------------- /tests/memcached/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # This file is open source software, licensed to you under the terms 4 | # of the Apache License, Version 2.0 (the "License"). See the NOTICE file 5 | # distributed with this work for additional information regarding copyright 6 | # ownership. You may not use this file except in compliance with the License. 7 | # 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | import time 20 | import sys 21 | import os 22 | import argparse 23 | import subprocess 24 | 25 | def run(args, cmd): 26 | mc = subprocess.Popen([os.path.join('build', args.mode, 'apps', 'memcached', 'memcached')]) 27 | print('Memcached started.') 28 | try: 29 | cmdline = ['tests/memcached/test_memcached.py'] + cmd 30 | if args.fast: 31 | cmdline.append('--fast') 32 | print('Running: ' + ' '.join(cmdline)) 33 | subprocess.check_call(cmdline) 34 | finally: 35 | print('Killing memcached...') 36 | mc.terminate(); 37 | mc.wait() 38 | print('Memcached killed.') 39 | 40 | if __name__ == "__main__": 41 | parser = argparse.ArgumentParser(description="Seastar test runner") 42 | parser.add_argument('--fast', action="store_true", help="Run only fast tests") 43 | parser.add_argument('--mode', action="store", help="Test app in given mode", default='release') 44 | args = parser.parse_args() 45 | 46 | run(args, []) 47 | run(args, ['-U']) 48 | -------------------------------------------------------------------------------- /kvm/README.md: -------------------------------------------------------------------------------- 1 | # seastar-in-kvm 2 | Create a VM for Seastar development environment 3 | 4 | # Why we need this 5 | SeaStar scores muximum performance with DPDK, but it cannot live with existing NIC driver/Linux kernel network stack. 6 | Also it directly accesses NIC device, it's bit hard to try it on remote node. 7 | 8 | seastar-in-kvm offers Fedora VM with SeaStar + DPDK without setup, it's easiest way to begin SeaStar application development. 9 | 10 | ### Prerequire 11 | 12 | On Fedora 21: 13 | ``` 14 | yum install @virtualization 15 | systemctl enable libvirtd 16 | systemctl start libvirtd 17 | yum install libguestfs-tools-c virt-install 18 | ``` 19 | 20 | ### How to build & run 21 | ``` 22 | ./build.sh 23 | ./register.sh 24 | virsh start seastar-dev && virsh console seastar-dev 25 | (Try login as 'seastar' after firstboot.sh finished, Fedora will ask new password for the user) 26 | ``` 27 | 28 | ### Usage of the VM 29 | 30 | Wait until finish running setup script on first startup. 31 | Then login as 'seastar', login prompt will ask for entering new password. 32 | 33 | After login to seastar, initialize DPDK module by following instruction: 34 | ``` 35 | sudo su - # entering root user 36 | resize # extend console to actual terminal window size 37 | export TERM=xterm-256color # set terminal type 38 | cd ~/dpdk 39 | ./tools/setup.sh 40 | 41 | # input numbers by following order: 42 | (type 9 to re-compile DPDK) 43 | (type 12 to insert IGB UIO module) 44 | (type 15, then input "64" to setup hugepage mappings) 45 | (type 18, then input PCI device id something like "0000:xx:yy.z", 46 | which is shown at 'Network devices using DPDK-compatible driver') 47 | (type 30 to exit) 48 | 49 | cd ~/seastar 50 | # httpd example 51 | env LD_LIBRARY_PATH=~/dpdk/x86_64-native-linuxapp-gcc/lib/ \ 52 | ./build/release/apps/httpd/httpd --network-stack native --dpdk-pmd --csum-offload off 53 | ``` 54 | 55 | 56 | -------------------------------------------------------------------------------- /net/packet-data-source.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | #ifndef _PACKET_DATA_SOURCE_HH 19 | #define _PACKET_DATA_SOURCE_HH 20 | 21 | #include "core/reactor.hh" 22 | #include "net/packet.hh" 23 | 24 | namespace net { 25 | 26 | class packet_data_source final : public data_source_impl { 27 | size_t _cur_frag = 0; 28 | packet _p; 29 | public: 30 | explicit packet_data_source(net::packet&& p) 31 | : _p(std::move(p)) 32 | {} 33 | 34 | virtual future> get() override { 35 | if (_cur_frag != _p.nr_frags()) { 36 | auto& f = _p.fragments()[_cur_frag++]; 37 | return make_ready_future>( 38 | temporary_buffer(f.base, f.size, 39 | make_deleter(deleter(), [p = _p.share()] () mutable {}))); 40 | } 41 | return make_ready_future>(temporary_buffer()); 42 | } 43 | }; 44 | 45 | static inline 46 | input_stream as_input_stream(packet&& p) { 47 | return input_stream(data_source(std::make_unique(std::move(p)))); 48 | } 49 | 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /net/udp.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | * 21 | */ 22 | 23 | #ifndef UDP_HH_ 24 | #define UDP_HH_ 25 | 26 | #include 27 | #include 28 | #include "core/reactor.hh" 29 | #include "core/shared_ptr.hh" 30 | #include "net/api.hh" 31 | #include "const.hh" 32 | #include "net.hh" 33 | 34 | namespace net { 35 | 36 | struct udp_hdr { 37 | packed src_port; 38 | packed dst_port; 39 | packed len; 40 | packed cksum; 41 | 42 | template 43 | auto adjust_endianness(Adjuster a) { 44 | return a(src_port, dst_port, len, cksum); 45 | } 46 | } __attribute__((packed)); 47 | 48 | struct udp_channel_state { 49 | queue _queue; 50 | // Limit number of data queued into send queue 51 | semaphore _user_queue_space = {212992}; 52 | udp_channel_state(size_t queue_size) : _queue(queue_size) {} 53 | future<> wait_for_send_buffer(size_t len) { return _user_queue_space.wait(len); } 54 | void complete_send(size_t len) { _user_queue_space.signal(len); } 55 | }; 56 | 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /util/transform_iterator.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef UTIL_TRANSFORM_ITERATOR_HH_ 23 | #define UTIL_TRANSFORM_ITERATOR_HH_ 24 | 25 | template 26 | class transform_iterator { 27 | Iterator _i; 28 | Func _f; 29 | public: 30 | transform_iterator(Iterator i, Func f) : _i(i), _f(f) {} 31 | auto operator*() { return _f(*_i); } 32 | transform_iterator& operator++() { 33 | ++_i; 34 | return *this; 35 | } 36 | transform_iterator operator++(int) { 37 | transform_iterator ret(*this); 38 | _i++; 39 | return ret; 40 | } 41 | bool operator==(const transform_iterator& x) const { 42 | return _i == x._i; 43 | } 44 | bool operator!=(const transform_iterator& x) const { 45 | return !operator==(x); 46 | } 47 | }; 48 | 49 | template 50 | inline 51 | transform_iterator 52 | make_transform_iterator(Iterator i, Func f) { 53 | return transform_iterator(i, f); 54 | } 55 | 56 | #endif /* UTIL_TRANSFORM_ITERATOR_HH_ */ 57 | -------------------------------------------------------------------------------- /tests/directory_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | 23 | #include "core/reactor.hh" 24 | #include "core/app-template.hh" 25 | #include "core/print.hh" 26 | #include "core/shared_ptr.hh" 27 | 28 | int main(int ac, char** av) { 29 | class lister { 30 | file _f; 31 | subscription _listing; 32 | public: 33 | lister(file f) 34 | : _f(std::move(f)) 35 | , _listing(_f.list_directory([this] (directory_entry de) { return report(de); })) { 36 | } 37 | future<> done() { return _listing.done(); } 38 | private: 39 | future<> report(directory_entry de) { 40 | print("%s\n", de.name); 41 | return make_ready_future<>(); 42 | } 43 | }; 44 | return app_template().run_deprecated(ac, av, [] { 45 | return engine().open_directory(".").then([] (file f) { 46 | auto l = make_lw_shared(std::move(f)); 47 | return l->done().then([l] { 48 | // ugly thing to keep *l alive 49 | engine().exit(0); 50 | }); 51 | }); 52 | }); 53 | } 54 | -------------------------------------------------------------------------------- /http/transformers.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #ifndef TRANSFORMERS_HH_ 23 | #define TRANSFORMERS_HH_ 24 | 25 | #include "handlers.hh" 26 | #include "file_handler.hh" 27 | 28 | namespace httpd { 29 | 30 | /** 31 | * content_replace replaces variable in a file with a dynamic value. 32 | * It would take the host from request and will replace the variable 33 | * in a file 34 | * 35 | * The replacement can be restricted to an extension. 36 | * 37 | * We are currently support only one file type for replacement. 38 | * It could be extend if we will need it 39 | * 40 | */ 41 | class content_replace : public file_transformer { 42 | public: 43 | virtual void transform(sstring& content, const request& req, 44 | const sstring& extension) override; 45 | /** 46 | * the constructor get the file extension the replace would work on. 47 | * @param extension file extension, when not set all files extension 48 | */ 49 | explicit content_replace(const sstring& extension = "") 50 | : extension(extension) { 51 | } 52 | private: 53 | sstring extension; 54 | }; 55 | 56 | } 57 | #endif /* TRANSFORMERS_HH_ */ 58 | -------------------------------------------------------------------------------- /http/common.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #ifndef COMMON_HH_ 23 | #define COMMON_HH_ 24 | 25 | #include 26 | #include "core/sstring.hh" 27 | 28 | namespace httpd { 29 | 30 | 31 | class parameters { 32 | std::unordered_map params; 33 | public: 34 | const sstring& path(const sstring& key) const { 35 | return params.at(key); 36 | } 37 | 38 | sstring operator[](const sstring& key) const { 39 | return params.at(key).substr(1); 40 | } 41 | 42 | const sstring& at(const sstring& key) const { 43 | return path(key); 44 | } 45 | 46 | bool exists(const sstring& key) const { 47 | return params.find(key) != params.end(); 48 | } 49 | 50 | void set(const sstring& key, const sstring& value) { 51 | params[key] = value; 52 | } 53 | 54 | void clear() { 55 | params.clear(); 56 | } 57 | 58 | }; 59 | 60 | enum operation_type { 61 | GET, POST, PUT, DELETE, NUM_OPERATION 62 | }; 63 | 64 | /** 65 | * Translate the string command to operation type 66 | * @param type the string "GET" or "POST" 67 | * @return the operation_type 68 | */ 69 | operation_type str2type(const sstring& type); 70 | 71 | } 72 | 73 | #endif /* COMMON_HH_ */ 74 | -------------------------------------------------------------------------------- /core/shared_ptr_debug_helper.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #pragma once 23 | 24 | #ifdef DEBUG_SHARED_PTR 25 | 26 | #include 27 | #include 28 | 29 | // A counter that is only comfortable being incremented on the cpu 30 | // it was created on. Useful for verifying that a shared_ptr 31 | // or lw_shared_ptr isn't misued across cores. 32 | class debug_shared_ptr_counter_type { 33 | long _counter = 0; 34 | std::thread::id _cpu = std::this_thread::get_id(); 35 | public: 36 | debug_shared_ptr_counter_type(long x) : _counter(x) {} 37 | operator long() const { 38 | check(); 39 | return _counter; 40 | } 41 | debug_shared_ptr_counter_type& operator++() { 42 | check(); 43 | ++_counter; 44 | return *this; 45 | } 46 | long operator++(int) { 47 | check(); 48 | return _counter++; 49 | } 50 | debug_shared_ptr_counter_type& operator--() { 51 | check(); 52 | --_counter; 53 | return *this; 54 | } 55 | long operator--(int) { 56 | check(); 57 | return _counter--; 58 | } 59 | private: 60 | void check() const { 61 | assert(_cpu == std::this_thread::get_id()); 62 | } 63 | }; 64 | 65 | #endif 66 | 67 | -------------------------------------------------------------------------------- /core/xen/evtchn.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | #ifndef _XEN_EVTCHN_HH 19 | #define _XEN_EVTCHN_HH 20 | 21 | #include "core/posix.hh" 22 | #include "core/future.hh" 23 | 24 | namespace xen { 25 | 26 | class evtchn; 27 | 28 | class port { 29 | int _port = -1; 30 | semaphore _sem; 31 | evtchn *_evtchn; 32 | public: 33 | explicit port(int p); 34 | port() = default; 35 | port(port&& other); 36 | ~port(); 37 | port& operator=(port&& other); 38 | int number() const { return _port; } 39 | future<> pending(); 40 | void notify(); 41 | void umask(); 42 | 43 | friend class evtchn; 44 | }; 45 | 46 | class evtchn { 47 | static evtchn *_instance; 48 | protected: 49 | unsigned _otherend; 50 | void make_ready_port(int port); 51 | void port_moved(int prt, port* old, port* now); 52 | void port_deleted(int prt, port* old); 53 | std::unordered_multimap _ports; 54 | virtual void notify(int port) = 0; 55 | virtual void umask(int *port, unsigned count) {}; 56 | friend class port; 57 | public: 58 | static evtchn *instance(bool userspace, unsigned otherend); 59 | static evtchn *instance(); 60 | evtchn(unsigned otherend) : _otherend(otherend) {} 61 | virtual port bind() = 0; 62 | port bind(int p) { return port(p); }; 63 | }; 64 | 65 | } 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /apps/memcached/memcached.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | #ifndef _MEMCACHED_HH 19 | #define _MEMCACHED_HH 20 | 21 | #include "core/sstring.hh" 22 | 23 | namespace memcache { 24 | 25 | class item; 26 | class cache; 27 | 28 | class item_key { 29 | private: 30 | sstring _key; 31 | size_t _hash; 32 | public: 33 | item_key() = default; 34 | item_key(item_key&) = default; 35 | item_key(sstring key) 36 | : _key(key) 37 | , _hash(std::hash()(key)) 38 | {} 39 | item_key(item_key&& other) 40 | : _key(std::move(other._key)) 41 | , _hash(other._hash) 42 | { 43 | other._hash = 0; 44 | } 45 | size_t hash() const { 46 | return _hash; 47 | } 48 | const sstring& key() const { 49 | return _key; 50 | } 51 | bool operator==(const item_key& other) const { 52 | return other._hash == _hash && other._key == _key; 53 | } 54 | void operator=(item_key&& other) { 55 | _key = std::move(other._key); 56 | _hash = other._hash; 57 | other._hash = 0; 58 | } 59 | }; 60 | 61 | } 62 | 63 | namespace std { 64 | 65 | template <> 66 | struct hash { 67 | size_t operator()(const memcache::item_key& key) { 68 | return key.hash(); 69 | } 70 | }; 71 | 72 | } /* namespace std */ 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /core/xen/osv_xen.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | #ifndef _XEN_HH 19 | #define _XEN_HH 20 | // Those should come directly from the OSv three. However, the xen exported 21 | // functions are not currently living in osv/include, but spread around the 22 | // BSD directory. We should move them there ASAP and then use them here. 23 | extern int 24 | bind_listening_port_to_irq(unsigned int remote_domain, int * port); 25 | extern int 26 | evtchn_from_irq(int irq); 27 | extern int 28 | notify_remote_via_evtchn(int port); 29 | extern void 30 | unmask_evtchn(int port); 31 | extern "C" int 32 | intr_add_handler(const char *name, int vector, void *filter, 33 | void (*handler)(void *arg), void *arg, int flags, 34 | void **cookiep); 35 | 36 | extern int 37 | gnttab_alloc_grant_references(uint16_t count, uint32_t *head); 38 | extern int 39 | gnttab_claim_grant_reference(uint32_t *private_head); 40 | 41 | extern int 42 | gnttab_grant_foreign_access(uint16_t domid, unsigned long frame, int readonly, uint32_t *result); 43 | extern void gnttab_grant_foreign_access_ref(uint32_t ref, uint16_t domid, unsigned long frame, int readonly); 44 | extern void 45 | gnttab_release_grant_reference(uint32_t *private_head, unsigned ref); 46 | extern int 47 | gnttab_end_foreign_access_ref(unsigned ref); 48 | 49 | extern "C" uint64_t 50 | virt_to_phys(void *virt); 51 | #endif 52 | -------------------------------------------------------------------------------- /core/dpdk_rte.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | #ifndef DPDK_RTE_HH_ 19 | #define DPDK_RTE_HH_ 20 | 21 | #ifdef HAVE_DPDK 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | /*********************** Compat section ***************************************/ 30 | // We currently support only versions 2.0 and above. 31 | #if (RTE_VERSION < RTE_VERSION_NUM(2,0,0,0)) 32 | #error "DPDK version above 2.0.0 is required" 33 | #endif 34 | 35 | #if defined(RTE_MBUF_REFCNT_ATOMIC) 36 | #warning "CONFIG_RTE_MBUF_REFCNT_ATOMIC should be disabled in DPDK's " \ 37 | "config/common_linuxapp" 38 | #endif 39 | /******************************************************************************/ 40 | 41 | namespace dpdk { 42 | 43 | // DPDK Environment Abstraction Layer 44 | class eal { 45 | public: 46 | using cpuset = std::bitset; 47 | 48 | static void init(cpuset cpus, boost::program_options::variables_map opts); 49 | /** 50 | * Returns the amount of memory needed for DPDK 51 | * @param num_cpus Number of CPUs the application is going to use 52 | * 53 | * @return 54 | */ 55 | static size_t mem_size(int num_cpus, bool hugetlbfs_membackend = true); 56 | static bool initialized; 57 | }; 58 | 59 | } // namespace dpdk 60 | #endif // HAVE_DPDK 61 | #endif // DPDK_RTE_HH_ 62 | -------------------------------------------------------------------------------- /net/ip_checksum.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef IP_CHECKSUM_HH_ 23 | #define IP_CHECKSUM_HH_ 24 | 25 | #include "packet.hh" 26 | #include 27 | #include 28 | #include 29 | 30 | namespace net { 31 | 32 | uint16_t ip_checksum(const void* data, size_t len); 33 | 34 | struct checksummer { 35 | __int128 csum = 0; 36 | bool odd = false; 37 | void sum(const char* data, size_t len); 38 | void sum(const packet& p); 39 | void sum(uint8_t data) { 40 | if (!odd) { 41 | csum += data << 8; 42 | } else { 43 | csum += data; 44 | } 45 | odd = !odd; 46 | } 47 | void sum(uint16_t data) { 48 | if (odd) { 49 | sum(uint8_t(data >> 8)); 50 | sum(uint8_t(data)); 51 | } else { 52 | csum += data; 53 | } 54 | } 55 | void sum(uint32_t data) { 56 | if (odd) { 57 | sum(uint16_t(data)); 58 | sum(uint16_t(data >> 16)); 59 | } else { 60 | csum += data; 61 | } 62 | } 63 | void sum_many() {} 64 | template 65 | void sum_many(T0 data, T... rest) { 66 | sum(data); 67 | sum_many(rest...); 68 | } 69 | uint16_t get() const; 70 | }; 71 | 72 | } 73 | 74 | #endif /* IP_CHECKSUM_HH_ */ 75 | -------------------------------------------------------------------------------- /core/apply.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef APPLY_HH_ 23 | #define APPLY_HH_ 24 | 25 | #include 26 | #include 27 | 28 | template 29 | struct apply_helper; 30 | 31 | template 32 | struct apply_helper> { 33 | static auto apply(Func&& func, Tuple args) { 34 | return func(std::get(std::forward(args))...); 35 | } 36 | }; 37 | 38 | template 39 | inline 40 | auto apply(Func&& func, std::tuple&& args) { 41 | using helper = apply_helper&&, std::index_sequence_for>; 42 | return helper::apply(std::forward(func), std::move(args)); 43 | } 44 | 45 | template 46 | inline 47 | auto apply(Func&& func, std::tuple& args) { 48 | using helper = apply_helper&, std::index_sequence_for>; 49 | return helper::apply(std::forward(func), args); 50 | } 51 | 52 | template 53 | inline 54 | auto apply(Func&& func, const std::tuple& args) { 55 | using helper = apply_helper&, std::index_sequence_for>; 56 | return helper::apply(std::forward(func), args); 57 | } 58 | 59 | #endif /* APPLY_HH_ */ 60 | -------------------------------------------------------------------------------- /core/function_traits.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | template 27 | struct function_traits; 28 | 29 | template 30 | struct function_traits 31 | { 32 | using return_type = Ret; 33 | using args_as_tuple = std::tuple; 34 | using signature = Ret (Args...); 35 | 36 | static constexpr std::size_t arity = sizeof...(Args); 37 | 38 | template 39 | struct arg 40 | { 41 | static_assert(N < arity, "no such parameter index."); 42 | using type = typename std::tuple_element>::type; 43 | }; 44 | }; 45 | 46 | template 47 | struct function_traits : public function_traits 48 | {}; 49 | 50 | template 51 | struct function_traits : public function_traits 52 | {}; 53 | 54 | template 55 | struct function_traits : public function_traits 56 | {}; 57 | 58 | template 59 | struct function_traits : public function_traits 60 | {}; 61 | 62 | template 63 | struct function_traits : public function_traits> 64 | {}; 65 | 66 | -------------------------------------------------------------------------------- /http/handlers.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #ifndef HANDLERS_HH_ 23 | #define HANDLERS_HH_ 24 | 25 | #include "request.hh" 26 | #include "common.hh" 27 | #include "reply.hh" 28 | #include "core/future-util.hh" 29 | 30 | #include 31 | 32 | namespace httpd { 33 | 34 | typedef const httpd::request& const_req; 35 | 36 | /** 37 | * handlers holds the logic for serving an incoming request. 38 | * All handlers inherit from the base httpserver_handler and 39 | * implement the handle method. 40 | * 41 | */ 42 | class handler_base { 43 | public: 44 | /** 45 | * All handlers should implement this method. 46 | * It fill the reply according to the request. 47 | * @param path the url path used in this call 48 | * @param params optional parameter object 49 | * @param req the original request 50 | * @param rep the reply 51 | */ 52 | virtual future > handle(const sstring& path, 53 | std::unique_ptr req, std::unique_ptr rep) = 0; 54 | 55 | virtual ~handler_base() = default; 56 | 57 | /** 58 | * Add a mandatory parameter 59 | * @param param a parameter name 60 | * @return a reference to the handler 61 | */ 62 | handler_base& mandatory(const sstring& param) { 63 | _mandatory_param.push_back(param); 64 | return *this; 65 | } 66 | 67 | std::vector _mandatory_param; 68 | 69 | }; 70 | 71 | } 72 | 73 | #endif /* HANDLERS_HH_ */ 74 | -------------------------------------------------------------------------------- /net/ethernet.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef ETHERNET_HH_ 23 | #define ETHERNET_HH_ 24 | 25 | #include 26 | #include "byteorder.hh" 27 | #include "core/print.hh" 28 | 29 | namespace net { 30 | 31 | struct ethernet_address { 32 | ethernet_address() {} 33 | 34 | ethernet_address(const uint8_t *eaddr) { 35 | std::copy(eaddr, eaddr + 6, mac.begin()); 36 | } 37 | 38 | ethernet_address(std::initializer_list eaddr) { 39 | assert(eaddr.size() == mac.size()); 40 | std::copy(eaddr.begin(), eaddr.end(), mac.begin()); 41 | } 42 | 43 | std::array mac; 44 | 45 | template 46 | void adjust_endianness(Adjuster a) {} 47 | } __attribute__((packed)); 48 | 49 | std::ostream& operator<<(std::ostream& os, ethernet_address ea); 50 | 51 | struct ethernet { 52 | using address = ethernet_address; 53 | static address broadcast_address() { 54 | return {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 55 | } 56 | static constexpr uint16_t arp_hardware_type() { return 1; } 57 | }; 58 | 59 | struct eth_hdr { 60 | ethernet_address dst_mac; 61 | ethernet_address src_mac; 62 | packed eth_proto; 63 | template 64 | auto adjust_endianness(Adjuster a) { 65 | return a(eth_proto); 66 | } 67 | } __attribute__((packed)); 68 | 69 | ethernet_address parse_ethernet_address(std::string addr); 70 | } 71 | 72 | #endif /* ETHERNET_HH_ */ 73 | -------------------------------------------------------------------------------- /tests/packet_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | 23 | #define BOOST_TEST_DYN_LINK 24 | #define BOOST_TEST_MODULE core 25 | 26 | #include 27 | #include "net/packet.hh" 28 | #include 29 | 30 | using namespace net; 31 | 32 | BOOST_AUTO_TEST_CASE(test_headers_are_contiguous) { 33 | using tcp_header = std::array; 34 | using ip_header = std::array; 35 | char data[1000] = {}; 36 | fragment f{data, sizeof(data)}; 37 | packet p(f); 38 | p.prepend_header(); 39 | p.prepend_header(); 40 | BOOST_REQUIRE_EQUAL(p.nr_frags(), 2); 41 | } 42 | 43 | BOOST_AUTO_TEST_CASE(test_headers_are_contiguous_even_with_small_fragment) { 44 | using tcp_header = std::array; 45 | using ip_header = std::array; 46 | char data[100] = {}; 47 | fragment f{data, sizeof(data)}; 48 | packet p(f); 49 | p.prepend_header(); 50 | p.prepend_header(); 51 | BOOST_REQUIRE_EQUAL(p.nr_frags(), 2); 52 | } 53 | 54 | BOOST_AUTO_TEST_CASE(test_headers_are_contiguous_even_with_many_fragments) { 55 | using tcp_header = std::array; 56 | using ip_header = std::array; 57 | char data[100] = {}; 58 | fragment f{data, sizeof(data)}; 59 | packet p(f); 60 | for (int i = 0; i < 7; ++i) { 61 | p.append(packet(f)); 62 | } 63 | p.prepend_header(); 64 | p.prepend_header(); 65 | BOOST_REQUIRE_EQUAL(p.nr_frags(), 9); 66 | } 67 | 68 | -------------------------------------------------------------------------------- /http/json_path.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #include "json_path.hh" 23 | 24 | namespace httpd { 25 | 26 | using namespace std; 27 | 28 | void path_description::set(routes& _routes, handler_base* handler) const { 29 | for (auto& i : mandatory_queryparams) { 30 | handler->mandatory(i); 31 | } 32 | 33 | if (params.size() == 0) 34 | _routes.put(operations.method, path, handler); 35 | else { 36 | match_rule* rule = new match_rule(handler); 37 | rule->add_str(path); 38 | for (auto i = params.begin(); i != params.end(); ++i) { 39 | rule->add_param(std::get<0>(*i), std::get<1>(*i)); 40 | } 41 | _routes.add(rule, operations.method); 42 | } 43 | } 44 | 45 | void path_description::set(routes& _routes, 46 | const json_request_function& f) const { 47 | set(_routes, new function_handler(f)); 48 | } 49 | 50 | void path_description::set(routes& _routes, const future_json_function& f) const { 51 | set(_routes, new function_handler(f)); 52 | } 53 | path_description::path_description(const sstring& path, operation_type method, 54 | const sstring& nickname, 55 | const std::vector>& path_parameters, 56 | const std::vector& mandatory_params) 57 | : path(path), operations(method, nickname) { 58 | 59 | for (auto man : mandatory_params) { 60 | pushmandatory_param(man); 61 | } 62 | for (auto param : path_parameters) { 63 | params.push_back(param); 64 | } 65 | 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /core/xen/gntalloc.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | #ifndef _XEN_GNTALLOC_HH 19 | #define _XEN_GNTALLOC_HH 20 | 21 | #include "core/posix.hh" 22 | 23 | namespace xen { 24 | 25 | class gntref { 26 | public: 27 | int xen_id; 28 | void* page; 29 | bool operator==(const gntref &a) { return (xen_id == a.xen_id) && (page == a.page); } 30 | gntref& operator=(const gntref &a) { xen_id = a.xen_id; page = a.page; return *this; } 31 | gntref(int id, void *page) : xen_id(id), page(page) {} 32 | gntref() : xen_id(-1), page(nullptr) {} 33 | operator bool() const { return xen_id != -1 && page != nullptr; } 34 | }; 35 | 36 | class gntalloc; 37 | 38 | class grant_head { 39 | protected: 40 | unsigned _id = 0; 41 | public: 42 | virtual ~grant_head() {} 43 | virtual gntref new_ref() = 0; 44 | virtual gntref new_ref(void *addr, size_t size) = 0; 45 | virtual void free_ref(gntref& ref) = 0; 46 | }; 47 | 48 | class gntalloc { 49 | protected: 50 | static gntalloc *_instance; 51 | unsigned _otherend; 52 | public: 53 | virtual ~gntalloc() {} 54 | static gntalloc *instance(bool userspace, unsigned otherend); 55 | static gntalloc *instance(); 56 | gntalloc(unsigned otherend) : _otherend(otherend) {} 57 | virtual gntref alloc_ref() = 0; 58 | // The kernel interface can defer allocation, userspace allocation 59 | // cannot. The boolean "alloc" tell us whether or not we should allocate 60 | // now or try to defer. 61 | virtual grant_head *alloc_ref(unsigned nr_ents) = 0; 62 | friend class grant_head; 63 | }; 64 | 65 | extern gntref invalid_ref; 66 | 67 | } 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /net/ip_checksum.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include "ip_checksum.hh" 23 | #include "net.hh" 24 | #include 25 | 26 | namespace net { 27 | 28 | void checksummer::sum(const char* data, size_t len) { 29 | auto orig_len = len; 30 | if (odd) { 31 | csum += uint8_t(*data++); 32 | --len; 33 | } 34 | auto p64 = reinterpret_cast*>(data); 35 | while (len >= 8) { 36 | csum += ntohq(*p64++); 37 | len -= 8; 38 | } 39 | auto p16 = reinterpret_cast*>(p64); 40 | while (len >= 2) { 41 | csum += ntohs(*p16++); 42 | len -= 2; 43 | } 44 | auto p8 = reinterpret_cast(p16); 45 | if (len) { 46 | csum += *p8++ << 8; 47 | len -= 1; 48 | } 49 | odd ^= orig_len & 1; 50 | } 51 | 52 | uint16_t checksummer::get() const { 53 | __int128 csum1 = (csum & 0xffff'ffff'ffff'ffff) + (csum >> 64); 54 | uint64_t csum = (csum1 & 0xffff'ffff'ffff'ffff) + (csum1 >> 64); 55 | csum = (csum & 0xffff) + ((csum >> 16) & 0xffff) + ((csum >> 32) & 0xffff) + (csum >> 48); 56 | csum = (csum & 0xffff) + (csum >> 16); 57 | csum = (csum & 0xffff) + (csum >> 16); 58 | return htons(~csum); 59 | } 60 | 61 | void checksummer::sum(const packet& p) { 62 | for (auto&& f : p.fragments()) { 63 | sum(f.base, f.size); 64 | } 65 | } 66 | 67 | uint16_t ip_checksum(const void* data, size_t len) { 68 | checksummer cksum; 69 | cksum.sum(reinterpret_cast(data), len); 70 | return cksum.get(); 71 | } 72 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /core/app-template.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | #ifndef _APP_TEMPLATE_HH 22 | #define _APP_TEMPLATE_HH 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | class app_template { 30 | private: 31 | boost::program_options::options_description _opts; 32 | boost::program_options::positional_options_description _pos_opts; 33 | boost::optional _configuration; 34 | public: 35 | struct positional_option { 36 | const char* name; 37 | const boost::program_options::value_semantic* value_semantic; 38 | const char* help; 39 | int max_count; 40 | }; 41 | public: 42 | app_template(); 43 | boost::program_options::options_description_easy_init add_options(); 44 | void add_positional_options(std::initializer_list options); 45 | boost::program_options::variables_map& configuration(); 46 | int run_deprecated(int ac, char ** av, std::function&& func); 47 | 48 | // Runs given function and terminates the application when the future it 49 | // returns resolves. The value with which the future resolves will be 50 | // returned by this function. 51 | int run(int ac, char ** av, std::function ()>&& func); 52 | 53 | // Like run_sync() which takes std::function()>, but returns 54 | // with exit code 0 when the future returned by func resolves 55 | // successfully. 56 | int run(int ac, char ** av, std::function ()>&& func); 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /http/matcher.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #include "matcher.hh" 23 | 24 | #include 25 | 26 | namespace httpd { 27 | 28 | using namespace std; 29 | 30 | /** 31 | * Search for the end of the url parameter. 32 | * @param url the url to search 33 | * @param ind the position in the url 34 | * @param entire_path when set to true, take all the reminaing url 35 | * when set to false, search for the next slash 36 | * @return the position in the url of the end of the parameter 37 | */ 38 | static size_t find_end_param(const sstring& url, size_t ind, bool entire_path) { 39 | size_t pos = (entire_path) ? url.length() : url.find('/', ind + 1); 40 | if (pos == sstring::npos) { 41 | return url.length(); 42 | } 43 | return pos; 44 | } 45 | 46 | size_t param_matcher::match(const sstring& url, size_t ind, parameters& param) { 47 | size_t last = find_end_param(url, ind, _entire_path); 48 | if (last == ind) { 49 | /* 50 | * empty parameter allows only for the case of entire_path 51 | */ 52 | if (_entire_path) { 53 | param.set(_name, ""); 54 | return ind; 55 | } 56 | return sstring::npos; 57 | } 58 | param.set(_name, url.substr(ind, last - ind)); 59 | return last; 60 | } 61 | 62 | size_t str_matcher::match(const sstring& url, size_t ind, parameters& param) { 63 | if (url.length() >= _len + ind && (url.find(_cmp, ind) == ind) 64 | && (url.length() == _len + ind || url.at(_len + ind) == '/')) { 65 | return _len + ind; 66 | } 67 | return sstring::npos; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /tests/blkdiscard_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include 23 | #include "core/app-template.hh" 24 | #include "core/future-util.hh" 25 | #include "core/file.hh" 26 | #include "core/reactor.hh" 27 | 28 | namespace bpo = boost::program_options; 29 | 30 | struct file_test { 31 | file_test(file&& f) : f(std::move(f)) {} 32 | file f; 33 | semaphore sem = { 0 }; 34 | }; 35 | 36 | int main(int ac, char** av) { 37 | app_template app; 38 | app.add_options() 39 | ("dev", bpo::value(), "e.g. --dev /dev/sdb") 40 | ; 41 | 42 | return app.run_deprecated(ac, av, [&app] { 43 | static constexpr auto max = 10000; 44 | auto&& config = app.configuration(); 45 | auto filepath = config["dev"].as(); 46 | 47 | engine().open_file_dma(filepath, open_flags::rw | open_flags::create).then([] (file f) { 48 | auto ft = new file_test{std::move(f)}; 49 | 50 | ft->f.stat().then([ft] (struct stat st) mutable { 51 | assert(S_ISBLK(st.st_mode)); 52 | auto offset = 0; 53 | auto length = max * 4096; 54 | ft->f.discard(offset, length).then([ft] () mutable { 55 | ft->sem.signal(); 56 | }); 57 | }); 58 | 59 | ft->sem.wait().then([ft] () mutable { 60 | return ft->f.flush(); 61 | }).then([ft] () mutable { 62 | std::cout << "done\n"; 63 | delete ft; 64 | engine().exit(0); 65 | }); 66 | }); 67 | }); 68 | } 69 | -------------------------------------------------------------------------------- /tests/exchanger.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | // Single-element blocking queue 29 | template 30 | class exchanger { 31 | private: 32 | std::mutex _mutex; 33 | std::condition_variable _cv; 34 | std::experimental::optional _element; 35 | std::exception_ptr _exception; 36 | private: 37 | void interrupt_ptr(std::exception_ptr e) { 38 | std::unique_lock lock(_mutex); 39 | if (!_exception) { 40 | _exception = e; 41 | _cv.notify_all(); 42 | } 43 | // FIXME: log if already interrupted 44 | } 45 | public: 46 | template 47 | void interrupt(Exception e) { 48 | try { 49 | throw e; 50 | } catch (...) { 51 | interrupt_ptr(std::current_exception()); 52 | } 53 | } 54 | void give(T value) { 55 | std::unique_lock lock(_mutex); 56 | _cv.wait(lock, [this] { return !_element || _exception; }); 57 | if (_exception) { 58 | std::rethrow_exception(_exception); 59 | } 60 | _element = value; 61 | _cv.notify_one(); 62 | } 63 | T take() { 64 | std::unique_lock lock(_mutex); 65 | _cv.wait(lock, [this] { return bool(_element) || _exception; }); 66 | if (_exception) { 67 | std::rethrow_exception(_exception); 68 | } 69 | auto v = *_element; 70 | _element = {}; 71 | _cv.notify_one(); 72 | return v; 73 | } 74 | }; 75 | -------------------------------------------------------------------------------- /json/formatter.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #include "formatter.hh" 23 | #include "json_elements.hh" 24 | 25 | using namespace std; 26 | 27 | namespace json { 28 | 29 | sstring formatter::to_json(const sstring& str) { 30 | return to_json(str.c_str()); 31 | } 32 | 33 | sstring formatter::to_json(const char* str) { 34 | sstring res = "\""; 35 | res += str; 36 | res += "\""; 37 | return res; 38 | } 39 | 40 | sstring formatter::to_json(int n) { 41 | return to_string(n); 42 | } 43 | 44 | sstring formatter::to_json(long n) { 45 | return to_string(n); 46 | } 47 | 48 | sstring formatter::to_json(float f) { 49 | if (std::isinf(f)) { 50 | throw out_of_range("Infinite float value is not supported"); 51 | } else if (std::isnan(f)) { 52 | throw invalid_argument("Invalid float value"); 53 | } 54 | return to_sstring(f); 55 | } 56 | 57 | sstring formatter::to_json(double d) { 58 | if (std::isinf(d)) { 59 | throw out_of_range("Infinite double value is not supported"); 60 | } else if (std::isnan(d)) { 61 | throw invalid_argument("Invalid double value"); 62 | } 63 | return to_sstring(d); 64 | } 65 | 66 | sstring formatter::to_json(bool b) { 67 | return (b) ? "true" : "false"; 68 | } 69 | 70 | sstring formatter::to_json(const date_time& d) { 71 | char buff[50]; 72 | sstring res = "\""; 73 | strftime(buff, 50, TIME_FORMAT, &d); 74 | res += buff; 75 | return res + "\""; 76 | } 77 | 78 | sstring formatter::to_json(const jsonable& obj) { 79 | return obj.to_json(); 80 | } 81 | 82 | sstring formatter::to_json(unsigned long l) { 83 | return to_string(l); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /http/httpd.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #include "core/reactor.hh" 23 | #include "core/sstring.hh" 24 | #include "core/app-template.hh" 25 | #include "core/circular_buffer.hh" 26 | #include "core/distributed.hh" 27 | #include "core/queue.hh" 28 | #include "core/future-util.hh" 29 | #include "core/scollectd.hh" 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include "httpd.hh" 39 | 40 | using namespace std::chrono_literals; 41 | 42 | namespace httpd { 43 | http_stats::http_stats(http_server& server) 44 | : _regs{ 45 | scollectd::add_polled_metric( 46 | scollectd::type_instance_id("httpd", scollectd::per_cpu_plugin_instance, 47 | "connections", "http-connections"), 48 | scollectd::make_typed(scollectd::data_type::DERIVE, 49 | [&server] { return server.total_connections(); })), 50 | scollectd::add_polled_metric( 51 | scollectd::type_instance_id("httpd", scollectd::per_cpu_plugin_instance, 52 | "current_connections", "current"), 53 | scollectd::make_typed(scollectd::data_type::GAUGE, 54 | [&server] { return server.current_connections(); })), 55 | scollectd::add_polled_metric( 56 | scollectd::type_instance_id("httpd", scollectd::per_cpu_plugin_instance, 57 | "http_requests", "served"), 58 | scollectd::make_typed(scollectd::data_type::DERIVE, 59 | [&server] { return server.requests_served(); })), 60 | } { 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tests/tcp_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include "net/ip.hh" 23 | #include "net/virtio.hh" 24 | #include "net/tcp.hh" 25 | 26 | using namespace net; 27 | 28 | struct tcp_test { 29 | ipv4& inet; 30 | using tcp = net::tcp; 31 | tcp::listener _listener; 32 | struct connection { 33 | tcp::connection tcp_conn; 34 | explicit connection(tcp::connection tc) : tcp_conn(std::move(tc)) {} 35 | void run() { 36 | tcp_conn.wait_for_data().then([this] { 37 | auto p = tcp_conn.read(); 38 | if (!p.len()) { 39 | tcp_conn.close_write(); 40 | return; 41 | } 42 | print("read %d bytes\n", p.len()); 43 | tcp_conn.send(std::move(p)); 44 | run(); 45 | }); 46 | } 47 | }; 48 | tcp_test(ipv4& inet) : inet(inet), _listener(inet.get_tcp().listen(10000)) {} 49 | void run() { 50 | _listener.accept().then([this] (tcp::connection conn) { 51 | (new connection(std::move(conn)))->run(); 52 | run(); 53 | }); 54 | } 55 | }; 56 | 57 | int main(int ac, char** av) { 58 | boost::program_options::variables_map opts; 59 | opts.insert(std::make_pair("tap-device", boost::program_options::variable_value(std::string("tap0"), false))); 60 | 61 | auto vnet = create_virtio_net_device(opts); 62 | interface netif(std::move(vnet)); 63 | ipv4 inet(&netif); 64 | inet.set_host_address(ipv4_address("192.168.122.2")); 65 | tcp_test tt(inet); 66 | engine().when_started().then([&tt] { tt.run(); }); 67 | engine().run(); 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /tests/test-utils.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | /* 20 | * Copyright (C) 2015 Cloudius Systems, Ltd. 21 | */ 22 | 23 | #include 24 | 25 | #include "tests/test-utils.hh" 26 | #include "core/future.hh" 27 | #include "core/app-template.hh" 28 | 29 | void seastar_test::run() { 30 | // HACK: please see https://github.com/cloudius-systems/seastar/issues/10 31 | BOOST_REQUIRE(true); 32 | 33 | // HACK: please see https://github.com/cloudius-systems/seastar/issues/10 34 | boost::program_options::variables_map()["dummy"]; 35 | 36 | global_test_runner().run_sync([this] { 37 | return run_test_case(); 38 | }); 39 | } 40 | 41 | // We store a pointer because tests are registered from dynamic initializers, 42 | // so we must ensure that 'tests' is initialized before any dynamic initializer. 43 | // I use a primitive type, which is guaranteed to be initialized before any 44 | // dynamic initializer and lazily allocate the factor. 45 | 46 | static std::vector* tests; 47 | 48 | seastar_test::seastar_test() { 49 | if (!tests) { 50 | tests = new std::vector(); 51 | } 52 | tests->push_back(this); 53 | } 54 | 55 | bool init_unit_test_suite() { 56 | auto&& ts = boost::unit_test::framework::master_test_suite(); 57 | ts.p_name.set(tests->size() ? (*tests)[0]->get_test_file() : "seastar-tests"); 58 | 59 | for (seastar_test* test : *tests) { 60 | ts.add(boost::unit_test::make_test_case([test] { test->run(); }, test->get_name()), 0, 0); 61 | } 62 | 63 | global_test_runner().start(ts.argc, ts.argv); 64 | return true; 65 | } 66 | 67 | int main(int ac, char** av) { 68 | return ::boost::unit_test::unit_test_main(&init_unit_test_suite, ac, av); 69 | } 70 | -------------------------------------------------------------------------------- /scripts/run_with_dpdk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ! 3 | # ! Usage: ./prepare_dpdk_env.sh [command parameters] 4 | # ! 5 | # ! Prepares the DPDK environment (binds a given NIC to UIO, allocates the required 6 | # ! number of huge pages) and executes the given command in it. 7 | # ! After the command terminates the original environment is restored apart from 8 | # ! huge pages, that remain allocated. 9 | # ! 10 | 11 | usage() 12 | { 13 | cat $0 | grep ^"# !" | cut -d"!" -f2- 14 | } 15 | 16 | # 17 | # check_stat_and_exit 18 | # 19 | check_stat_and_exit() 20 | { 21 | if [[ $? -ne 0 ]]; then 22 | echo $@ 23 | exit 1 24 | fi 25 | } 26 | 27 | rollback() 28 | { 29 | echo "Binding $NIC($BDF) back to $DRIVER..." 30 | $SCRIPTS_DIR/dpdk_nic_bind.py -u $BDF 31 | $SCRIPTS_DIR/dpdk_nic_bind.py -b $DRIVER $BDF 32 | } 33 | 34 | check_stat_and_rollback() 35 | { 36 | if [[ $? -ne 0 ]]; then 37 | echo $@ 38 | rollback 39 | exit 1 40 | fi 41 | } 42 | 43 | # Check number of parameters 44 | if [[ $# -lt 3 ]]; then 45 | usage 46 | exit 1 47 | fi 48 | 49 | NIC=$1 50 | shift 51 | NUM_HUGE_PAGES_PER_NODE=$1 52 | shift 53 | SCRIPTS_DIR=`dirname $0` 54 | 55 | 56 | ifconfig $NIC down 57 | check_stat_and_exit "Failed to shut down $NIC. Is $NIC present? Are your permissions sufficient?" 58 | 59 | DRIVER=`ethtool -i $NIC | grep driver | cut -d":" -f2- | tr -d ' '` 60 | BDF=`ethtool -i $NIC | grep bus-info | cut -d":" -f2- | tr -d ' '` 61 | 62 | # command to execute 63 | CMD=$@ 64 | 65 | echo "Binding $NIC($BDF) to uio_pci_generic..." 66 | $SCRIPTS_DIR/dpdk_nic_bind.py -u $BDF 67 | check_stat_and_exit 68 | $SCRIPTS_DIR/dpdk_nic_bind.py -b uio_pci_generic $BDF 69 | check_stat_and_rollback 70 | 71 | echo "Allocating $NUM_HUGE_PAGES_PER_NODE 2MB huge pages on each NUMA Node:" 72 | for d in /sys/devices/system/node/node? ; do 73 | echo $NUM_HUGE_PAGES_PER_NODE > $d/hugepages/hugepages-2048kB/nr_hugepages 74 | check_stat_and_rollback 75 | cur_node=`basename $d` 76 | echo "...$cur_node done..." 77 | done 78 | 79 | mkdir -p /mnt/huge 80 | check_stat_and_rollback 81 | 82 | grep -s '/mnt/huge' /proc/mounts > /dev/null 83 | if [[ $? -ne 0 ]] ; then 84 | echo "Mounting hugetlbfs at /mnt/huge..." 85 | mount -t hugetlbfs nodev /mnt/huge 86 | check_stat_and_rollback 87 | fi 88 | 89 | # Run scylla 90 | echo "Running: $CMD" 91 | $CMD 92 | ret=$? 93 | 94 | # Revert the NIC binding 95 | rollback 96 | 97 | exit $ret 98 | 99 | -------------------------------------------------------------------------------- /net/proxy.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | #include "core/reactor.hh" 19 | #include "proxy.hh" 20 | #include 21 | 22 | namespace net { 23 | 24 | class proxy_net_device : public qp { 25 | private: 26 | static constexpr size_t _send_queue_length = 128; 27 | size_t _send_depth = 0; 28 | unsigned _cpu; 29 | device* _dev; 30 | std::vector _moving; 31 | public: 32 | explicit proxy_net_device(unsigned cpu, device* dev); 33 | virtual future<> send(packet p) override { 34 | abort(); 35 | } 36 | virtual uint32_t send(circular_buffer& p) override; 37 | }; 38 | 39 | proxy_net_device::proxy_net_device(unsigned cpu, device* dev) : 40 | _cpu(cpu), 41 | _dev(dev) 42 | { 43 | _moving.reserve(_send_queue_length); 44 | } 45 | 46 | uint32_t proxy_net_device::send(circular_buffer& p) 47 | { 48 | if (!_moving.empty() || _send_depth == _send_queue_length) { 49 | return 0; 50 | } 51 | 52 | for (size_t i = 0; !p.empty() && _send_depth < _send_queue_length; i++, _send_depth++) { 53 | _moving.push_back(std::move(p.front())); 54 | p.pop_front(); 55 | } 56 | 57 | if (!_moving.empty()) { 58 | qp* dev = &_dev->queue_for_cpu(_cpu); 59 | auto cpu = engine().cpu_id(); 60 | smp::submit_to(_cpu, [this, dev, cpu]() mutable { 61 | for(size_t i = 0; i < _moving.size(); i++) { 62 | dev->proxy_send(_moving[i].free_on_cpu(cpu, [this] { _send_depth--; })); 63 | } 64 | }).then([this] { 65 | _moving.clear(); 66 | }); 67 | } 68 | 69 | return _moving.size(); 70 | } 71 | 72 | std::unique_ptr create_proxy_net_device(unsigned master_cpu, device* dev) { 73 | return std::make_unique(master_cpu, dev); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /util/function_input_iterator.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef UTIL_FUNCTION_INPUT_ITERATOR_HH_ 23 | #define UTIL_FUNCTION_INPUT_ITERATOR_HH_ 24 | 25 | template 26 | struct function_input_iterator { 27 | Function _func; 28 | State _state; 29 | public: 30 | function_input_iterator(Function func, State state) 31 | : _func(func), _state(state) { 32 | } 33 | function_input_iterator(const function_input_iterator&) = default; 34 | function_input_iterator(function_input_iterator&&) = default; 35 | function_input_iterator& operator=(const function_input_iterator&) = default; 36 | function_input_iterator& operator=(function_input_iterator&&) = default; 37 | auto operator*() const { 38 | return _func(); 39 | } 40 | function_input_iterator& operator++() { 41 | ++_state; 42 | return *this; 43 | } 44 | function_input_iterator operator++(int) { 45 | function_input_iterator ret{*this}; 46 | ++_state; 47 | return ret; 48 | } 49 | bool operator==(const function_input_iterator& x) const { 50 | return _state == x._state; 51 | } 52 | bool operator!=(const function_input_iterator& x) const { 53 | return !operator==(x); 54 | } 55 | }; 56 | 57 | template 58 | inline 59 | function_input_iterator 60 | make_function_input_iterator(Function func, State state) { 61 | return function_input_iterator(func, state); 62 | } 63 | 64 | template 65 | inline 66 | function_input_iterator 67 | make_function_input_iterator(Function&& func) { 68 | return function_input_iterator(func, State{}); 69 | } 70 | 71 | #endif /* UTIL_FUNCTION_INPUT_ITERATOR_HH_ */ 72 | -------------------------------------------------------------------------------- /tests/smp_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include "core/reactor.hh" 23 | #include "core/app-template.hh" 24 | #include "core/print.hh" 25 | 26 | future test_smp_call() { 27 | return smp::submit_to(1, [] { 28 | return make_ready_future(3); 29 | }).then([] (int ret) { 30 | return make_ready_future(ret == 3); 31 | }); 32 | } 33 | 34 | struct nasty_exception {}; 35 | 36 | future test_smp_exception() { 37 | print("1\n"); 38 | return smp::submit_to(1, [] { 39 | print("2\n"); 40 | auto x = make_exception_future(nasty_exception()); 41 | print("3\n"); 42 | return x; 43 | }).then_wrapped([] (future result) { 44 | print("4\n"); 45 | try { 46 | result.get(); 47 | return make_ready_future(false); // expected an exception 48 | } catch (nasty_exception&) { 49 | // all is well 50 | return make_ready_future(true); 51 | } catch (...) { 52 | // incorrect exception type 53 | return make_ready_future(false); 54 | } 55 | }); 56 | } 57 | 58 | int tests, fails; 59 | 60 | future<> 61 | report(sstring msg, future&& result) { 62 | return std::move(result).then([msg] (bool result) { 63 | print("%s: %s\n", (result ? "PASS" : "FAIL"), msg); 64 | tests += 1; 65 | fails += !result; 66 | }); 67 | } 68 | 69 | int main(int ac, char** av) { 70 | return app_template().run_deprecated(ac, av, [] { 71 | return report("smp call", test_smp_call()).then([] { 72 | return report("smp exception", test_smp_exception()); 73 | }).then([] { 74 | print("\n%d tests / %d failures\n", tests, fails); 75 | engine().exit(fails ? 1 : 0); 76 | }); 77 | }); 78 | } 79 | -------------------------------------------------------------------------------- /net/dhcp.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2014 Cloudius Systems 20 | */ 21 | 22 | #ifndef NET_DHCP_HH_ 23 | #define NET_DHCP_HH_ 24 | 25 | #include "ip.hh" 26 | #include "core/reactor.hh" 27 | 28 | namespace net { 29 | 30 | /* 31 | * Simplistic DHCP query class. 32 | * Due to the nature of the native stack, 33 | * it operates on an "ipv4" object instead of, 34 | * for example, an interface. 35 | */ 36 | class dhcp { 37 | public: 38 | dhcp(ipv4 &); 39 | dhcp(dhcp &&); 40 | ~dhcp(); 41 | 42 | static const clock_type::duration default_timeout; 43 | 44 | struct lease { 45 | ipv4_address ip; 46 | ipv4_address netmask; 47 | ipv4_address broadcast; 48 | 49 | ipv4_address gateway; 50 | ipv4_address dhcp_server; 51 | 52 | std::vector name_servers; 53 | 54 | std::chrono::seconds lease_time; 55 | std::chrono::seconds renew_time; 56 | std::chrono::seconds rebind_time; 57 | 58 | uint16_t mtu = 0; 59 | }; 60 | 61 | typedef future result_type; 62 | 63 | /** 64 | * Runs a discover/request sequence on the ipv4 "stack". 65 | * During this execution the ipv4 will be "hijacked" 66 | * more or less (through packet filter), and while not 67 | * inoperable, most likely quite less efficient. 68 | * 69 | * Please note that this does _not_ modify the ipv4 object bound. 70 | * It only makes queries and records replys for the related NIC. 71 | * It is up to caller to use the returned information as he se fit. 72 | */ 73 | result_type discover(const clock_type::duration & = default_timeout); 74 | result_type renew(const lease &, const clock_type::duration & = default_timeout); 75 | ip_packet_filter* get_ipv4_filter(); 76 | private: 77 | class impl; 78 | std::unique_ptr _impl; 79 | }; 80 | 81 | } 82 | 83 | #endif /* NET_DHCP_HH_ */ 84 | -------------------------------------------------------------------------------- /core/timer.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include "future.hh" 27 | #include "timer-set.hh" 28 | 29 | using clock_type = std::chrono::high_resolution_clock; 30 | 31 | template 32 | class timer { 33 | public: 34 | typedef typename Clock::time_point time_point; 35 | typedef typename Clock::duration duration; 36 | typedef Clock clock; 37 | private: 38 | using callback_t = std::function; 39 | boost::intrusive::list_member_hook<> _link; 40 | callback_t _callback; 41 | time_point _expiry; 42 | std::experimental::optional _period; 43 | bool _armed = false; 44 | bool _queued = false; 45 | bool _expired = false; 46 | void readd_periodic(); 47 | void arm_state(time_point until, std::experimental::optional period); 48 | public: 49 | timer() = default; 50 | timer(timer&& t) noexcept : _callback(std::move(t._callback)), _expiry(std::move(t._expiry)), _period(std::move(t._period)), 51 | _armed(t._armed), _queued(t._queued), _expired(t._expired) { 52 | _link.swap_nodes(t._link); 53 | t._queued = false; 54 | t._armed = false; 55 | } 56 | explicit timer(callback_t&& callback); 57 | ~timer(); 58 | future<> expired(); 59 | void set_callback(callback_t&& callback); 60 | void arm(time_point until, std::experimental::optional period = {}); 61 | void rearm(time_point until, std::experimental::optional period = {}); 62 | void arm(duration delta); 63 | void arm_periodic(duration delta); 64 | bool armed() const { return _armed; } 65 | bool cancel(); 66 | time_point get_timeout(); 67 | friend class reactor; 68 | friend class seastar::timer_set; 69 | }; 70 | 71 | -------------------------------------------------------------------------------- /core/transfer.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef TRANSFER_HH_ 23 | #define TRANSFER_HH_ 24 | 25 | // Helper functions for copying or moving multiple objects in an exception 26 | // safe manner, then destroying the sources. 27 | // 28 | // To transfer, call transfer_pass1(allocator, &from, &to) on all object pairs, 29 | // (this copies the object from @from to @to). If no exceptions are encountered, 30 | // call transfer_pass2(allocator, &from, &to). This destroys the object at the 31 | // origin. If exceptions were encountered, simply destroy all copied objects. 32 | // 33 | // As an optimization, if the objects are moveable without throwing (noexcept) 34 | // transfer_pass1() simply moves the objects and destroys the source, and 35 | // transfer_pass2() does nothing. 36 | 37 | #include 38 | #include 39 | 40 | template 41 | inline 42 | void 43 | transfer_pass1(Alloc& a, T* from, T* to, 44 | typename std::enable_if::value>::type* = nullptr) { 45 | a.construct(to, std::move(*from)); 46 | a.destroy(from); 47 | } 48 | 49 | template 50 | inline 51 | void 52 | transfer_pass2(Alloc& a, T* from, T* to, 53 | typename std::enable_if::value>::type* = nullptr) { 54 | } 55 | 56 | template 57 | inline 58 | void 59 | transfer_pass1(Alloc& a, T* from, T* to, 60 | typename std::enable_if::value>::type* = nullptr) { 61 | a.construct(to, *from); 62 | } 63 | 64 | template 65 | inline 66 | void 67 | transfer_pass2(Alloc& a, T* from, T* to, 68 | typename std::enable_if::value>::type* = nullptr) { 69 | a.destroy(from); 70 | } 71 | 72 | #endif /* TRANSFER_HH_ */ 73 | -------------------------------------------------------------------------------- /net/arp.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include "arp.hh" 23 | 24 | namespace net { 25 | 26 | arp_for_protocol::arp_for_protocol(arp& a, uint16_t proto_num) 27 | : _arp(a), _proto_num(proto_num) { 28 | _arp.add(proto_num, this); 29 | } 30 | 31 | arp_for_protocol::~arp_for_protocol() { 32 | _arp.del(_proto_num); 33 | } 34 | 35 | arp::arp(interface* netif) : _netif(netif), _proto(netif, eth_protocol_num::arp, [this] { return get_packet(); }) 36 | , _rx_packets(_proto.receive([this] (packet p, ethernet_address ea) { 37 | return process_packet(std::move(p), ea); 38 | }, 39 | [this](forward_hash& out_hash_data, packet& p, size_t off) { 40 | return forward(out_hash_data, p, off); 41 | })) { 42 | } 43 | 44 | std::experimental::optional arp::get_packet() { 45 | std::experimental::optional p; 46 | if (!_packetq.empty()) { 47 | p = std::move(_packetq.front()); 48 | _packetq.pop_front(); 49 | } 50 | return p; 51 | } 52 | 53 | bool arp::forward(forward_hash& out_hash_data, packet& p, size_t off) { 54 | auto ah = p.get_header(off); 55 | auto i = _arp_for_protocol.find(ntoh(ah->ptype)); 56 | if (i != _arp_for_protocol.end()) { 57 | return i->second->forward(out_hash_data, p, off); 58 | } 59 | return false; 60 | } 61 | 62 | void arp::add(uint16_t proto_num, arp_for_protocol* afp) { 63 | _arp_for_protocol[proto_num] = afp; 64 | } 65 | 66 | void arp::del(uint16_t proto_num) { 67 | _arp_for_protocol.erase(proto_num); 68 | } 69 | 70 | future<> 71 | arp::process_packet(packet p, ethernet_address from) { 72 | auto ah = ntoh(*p.get_header()); 73 | auto i = _arp_for_protocol.find(ah.ptype); 74 | if (i != _arp_for_protocol.end()) { 75 | i->second->received(std::move(p)); 76 | } 77 | return make_ready_future<>(); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /apps/httpd/demo.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "0.0.1", 3 | "swaggerVersion": "1.2", 4 | "basePath": "{{Protocol}}://{{Host}}", 5 | "resourcePath": "/hello", 6 | "produces": [ 7 | "application/json" 8 | ], 9 | "apis": [ 10 | { 11 | "path": "/hello/world/{var1}/{var2}", 12 | "operations": [ 13 | { 14 | "method": "GET", 15 | "summary": "Returns the number of seconds since the system was booted", 16 | "type": "long", 17 | "nickname": "hello_world", 18 | "produces": [ 19 | "application/json" 20 | ], 21 | "parameters": [ 22 | { 23 | "name":"var2", 24 | "description":"Full path of file or directory", 25 | "required":true, 26 | "allowMultiple":true, 27 | "type":"string", 28 | "paramType":"path" 29 | }, 30 | { 31 | "name":"var1", 32 | "description":"Full path of file or directory", 33 | "required":true, 34 | "allowMultiple":false, 35 | "type":"string", 36 | "paramType":"path" 37 | }, 38 | { 39 | "name":"query_enum", 40 | "description":"The operation to perform", 41 | "required":true, 42 | "allowMultiple":false, 43 | "type":"string", 44 | "paramType":"query", 45 | "enum":["VAL1", "VAL2", "VAL3"] 46 | } 47 | ] 48 | } 49 | ] 50 | } 51 | ], 52 | "models" : { 53 | "my_object": { 54 | "id": "my_object", 55 | "description": "Demonstrate an object", 56 | "properties": { 57 | "var1": { 58 | "type": "string", 59 | "description": "The first parameter in the path" 60 | }, 61 | "var2": { 62 | "type": "string", 63 | "description": "The second parameter in the path" 64 | }, 65 | "enum_var" : { 66 | "type": "string", 67 | "description": "Demonstrate an enum returned, note this is not the same enum type of the request", 68 | "enum":["VAL1", "VAL2", "VAL3"] 69 | } 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /rpc/rpc_types.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #pragma once 23 | 24 | #include "net/api.hh" 25 | #include 26 | #include 27 | #include 28 | 29 | namespace rpc { 30 | 31 | // used to tag a type for serializers 32 | template 33 | struct type { 34 | }; 35 | 36 | struct stats { 37 | using counter_type = uint64_t; 38 | counter_type replied = 0; 39 | counter_type pending = 0; 40 | counter_type exception_received = 0; 41 | counter_type sent_messages = 0; 42 | counter_type wait_reply = 0; 43 | counter_type timeout = 0; 44 | }; 45 | 46 | 47 | struct client_info { 48 | socket_address addr; 49 | std::unordered_map user_data; 50 | template 51 | void attach_auxiliary(const sstring& key, T&& object) { 52 | user_data.emplace(key, boost::any(std::forward(object))); 53 | } 54 | template 55 | T& retrieve_auxiliary(const sstring& key) { 56 | auto it = user_data.find(key); 57 | assert(it != user_data.end()); 58 | return boost::any_cast(it->second); 59 | } 60 | template 61 | typename std::add_const::type& retrieve_auxiliary(const sstring& key) const { 62 | return const_cast(this)->retrieve_auxiliary::type>(key); 63 | } 64 | }; 65 | 66 | class error : public std::runtime_error { 67 | public: 68 | error(const std::string& msg) : std::runtime_error(msg) {} 69 | }; 70 | 71 | class closed_error : public error { 72 | public: 73 | closed_error() : error("connection is closed") {} 74 | }; 75 | 76 | class timeout_error : public error { 77 | public: 78 | timeout_error() : error("rpc call timed out") {} 79 | }; 80 | 81 | struct no_wait_type {}; 82 | 83 | // return this from a callback if client does not want to waiting for a reply 84 | extern no_wait_type no_wait; 85 | 86 | } // namespace rpc 87 | -------------------------------------------------------------------------------- /core/xen/xenstore.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | #include "core/reactor.hh" 19 | #include "xenstore.hh" 20 | #include 21 | #include 22 | 23 | using xenstore_transaction = xenstore::xenstore_transaction; 24 | 25 | xenstore_transaction xenstore::_xs_null = xenstore::xenstore_transaction(); 26 | xenstore *xenstore::_instance = nullptr; 27 | 28 | xenstore *xenstore::instance() { 29 | 30 | if (!_instance) { 31 | _instance = new xenstore; 32 | } 33 | return _instance; 34 | } 35 | 36 | xenstore::xenstore() 37 | : _h(xs_daemon_open()) 38 | { 39 | if (!_h) { 40 | throw std::runtime_error("Failed to initialize xenstore"); 41 | } 42 | } 43 | 44 | xenstore::~xenstore() 45 | { 46 | xs_close(_h); 47 | } 48 | 49 | xs_transaction_t xenstore::start_transaction() 50 | { 51 | auto t = xs_transaction_start(_h); 52 | if (!t) { 53 | throw std::runtime_error("Failed to initialize xenstore transaction"); 54 | } 55 | return t; 56 | } 57 | 58 | void xenstore::end_transaction(xs_transaction_t t) 59 | { 60 | xs_transaction_end(_h, t, false); 61 | } 62 | 63 | void xenstore::write(std::string path, std::string value, xenstore_transaction &t) 64 | { 65 | xs_write(_h, t.t(), path.c_str(), value.c_str(), value.size()); 66 | } 67 | 68 | void xenstore::remove(std::string path, xenstore_transaction &t) 69 | { 70 | xs_rm(_h, t.t(), path.c_str()); 71 | } 72 | 73 | std::string xenstore::read(std::string path, xenstore_transaction &t) 74 | { 75 | unsigned int len; 76 | void *ret = xs_read(_h, t.t(), path.c_str(), &len); 77 | std::string str(ret ? (const char *)ret : ""); 78 | free(ret); 79 | return str; 80 | } 81 | 82 | std::list xenstore::ls(std::string path, xenstore_transaction &t) 83 | { 84 | unsigned int num; 85 | char **dir = xs_directory(_h, t.t(), path.c_str(), &num); 86 | 87 | std::list names; 88 | for (unsigned int i = 0; i < num; ++i) { 89 | names.push_back(dir[i]); 90 | } 91 | free(dir); 92 | 93 | return names; 94 | } 95 | -------------------------------------------------------------------------------- /tests/udp_server.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include "core/distributed.hh" 23 | #include "core/app-template.hh" 24 | #include "core/future-util.hh" 25 | 26 | using namespace net; 27 | using namespace std::chrono_literals; 28 | 29 | class udp_server { 30 | private: 31 | udp_channel _chan; 32 | timer<> _stats_timer; 33 | uint64_t _n_sent {}; 34 | public: 35 | void start(uint16_t port) { 36 | ipv4_addr listen_addr{port}; 37 | _chan = engine().net().make_udp_channel(listen_addr); 38 | 39 | _stats_timer.set_callback([this] { 40 | std::cout << "Out: " << _n_sent << " pps" << std::endl; 41 | _n_sent = 0; 42 | }); 43 | _stats_timer.arm_periodic(1s); 44 | 45 | keep_doing([this] { 46 | return _chan.receive().then([this] (udp_datagram dgram) { 47 | return _chan.send(dgram.get_src(), std::move(dgram.get_data())).then([this] { 48 | _n_sent++; 49 | }); 50 | }); 51 | }); 52 | } 53 | // FIXME: we should properly tear down the service here. 54 | future<> stop() { 55 | return make_ready_future<>(); 56 | } 57 | }; 58 | 59 | namespace bpo = boost::program_options; 60 | 61 | int main(int ac, char ** av) { 62 | app_template app; 63 | app.add_options() 64 | ("port", bpo::value()->default_value(10000), "UDP server port") ; 65 | return app.run_deprecated(ac, av, [&] { 66 | auto&& config = app.configuration(); 67 | uint16_t port = config["port"].as(); 68 | auto server = new distributed; 69 | server->start().then([server = std::move(server), port] () mutable { 70 | engine().at_exit([server] { 71 | return server->stop(); 72 | }); 73 | server->invoke_on_all(&udp_server::start, port); 74 | }).then([port] { 75 | std::cout << "Seastar UDP server listening on port " << port << " ...\n"; 76 | }); 77 | }); 78 | } 79 | -------------------------------------------------------------------------------- /tests/udp_client.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include "core/app-template.hh" 23 | #include "core/future-util.hh" 24 | #include "core/reactor.hh" 25 | #include "net/api.hh" 26 | 27 | using namespace net; 28 | using namespace std::chrono_literals; 29 | 30 | class client { 31 | private: 32 | udp_channel _chan; 33 | uint64_t n_sent {}; 34 | uint64_t n_received {}; 35 | uint64_t n_failed {}; 36 | timer<> _stats_timer; 37 | public: 38 | void start(ipv4_addr server_addr) { 39 | std::cout << "Sending to " << server_addr << std::endl; 40 | 41 | _chan = engine().net().make_udp_channel(); 42 | 43 | _stats_timer.set_callback([this] { 44 | std::cout << "Out: " << n_sent << " pps, \t"; 45 | std::cout << "Err: " << n_failed << " pps, \t"; 46 | std::cout << "In: " << n_received << " pps" << std::endl; 47 | n_sent = 0; 48 | n_received = 0; 49 | n_failed = 0; 50 | }); 51 | _stats_timer.arm_periodic(1s); 52 | 53 | keep_doing([this, server_addr] { 54 | return _chan.send(server_addr, "hello!\n") 55 | .then_wrapped([this] (auto&& f) { 56 | try { 57 | f.get(); 58 | n_sent++; 59 | } catch (...) { 60 | n_failed++; 61 | } 62 | }); 63 | }); 64 | 65 | keep_doing([this] { 66 | return _chan.receive().then([this] (auto) { 67 | n_received++; 68 | }); 69 | }); 70 | } 71 | }; 72 | 73 | namespace bpo = boost::program_options; 74 | 75 | int main(int ac, char ** av) { 76 | client _client; 77 | app_template app; 78 | app.add_options() 79 | ("server", bpo::value(), "Server address") 80 | ; 81 | return app.run_deprecated(ac, av, [&_client, &app] { 82 | auto&& config = app.configuration(); 83 | _client.start(config["server"].as()); 84 | }); 85 | } 86 | -------------------------------------------------------------------------------- /tests/fileiotest.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014-2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include "tests/test-utils.hh" 23 | 24 | #include "core/semaphore.hh" 25 | #include "core/file.hh" 26 | #include "core/reactor.hh" 27 | 28 | struct file_test { 29 | file_test(file&& f) : f(std::move(f)) {} 30 | file f; 31 | semaphore sem = { 0 }; 32 | semaphore par = { 1000 }; 33 | }; 34 | 35 | SEASTAR_TEST_CASE(test1) { 36 | // Note: this tests generates a file "testfile.tmp" with size 4096 * max (= 40 MB). 37 | static constexpr auto max = 10000; 38 | return open_file_dma("testfile.tmp", open_flags::rw | open_flags::create).then([] (file f) { 39 | auto ft = new file_test{std::move(f)}; 40 | for (size_t i = 0; i < max; ++i) { 41 | ft->par.wait().then([ft, i] { 42 | auto wbuf = allocate_aligned_buffer(4096, 4096); 43 | std::fill(wbuf.get(), wbuf.get() + 4096, i); 44 | auto wb = wbuf.get(); 45 | ft->f.dma_write(i * 4096, wb, 4096).then( 46 | [ft, i, wbuf = std::move(wbuf)] (size_t ret) mutable { 47 | BOOST_REQUIRE(ret == 4096); 48 | auto rbuf = allocate_aligned_buffer(4096, 4096); 49 | auto rb = rbuf.get(); 50 | ft->f.dma_read(i * 4096, rb, 4096).then( 51 | [ft, i, rbuf = std::move(rbuf), wbuf = std::move(wbuf)] (size_t ret) mutable { 52 | BOOST_REQUIRE(ret == 4096); 53 | BOOST_REQUIRE(std::equal(rbuf.get(), rbuf.get() + 4096, wbuf.get())); 54 | ft->sem.signal(1); 55 | ft->par.signal(); 56 | }); 57 | }); 58 | }); 59 | } 60 | return ft->sem.wait(max).then([ft] () mutable { 61 | return ft->f.flush(); 62 | }).then([ft] { 63 | return ft->f.close(); 64 | }).then([ft] () mutable { 65 | std::cout << "done\n"; 66 | delete ft; 67 | }); 68 | }); 69 | } 70 | 71 | 72 | -------------------------------------------------------------------------------- /tests/linecount.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | // Demonstration of file_input_stream. Don't expect stellar performance 23 | // since no read-ahead or caching is done yet. 24 | 25 | #include "core/fstream.hh" 26 | #include "core/app-template.hh" 27 | #include "core/shared_ptr.hh" 28 | #include "core/reactor.hh" 29 | #include 30 | 31 | struct reader { 32 | reader(file f) : is(make_file_input_stream(std::move(f), 0, 4096)) {} 33 | input_stream is; 34 | size_t count = 0; 35 | 36 | // for input_stream::consume(): 37 | using unconsumed_remainder = std::experimental::optional>; 38 | future operator()(temporary_buffer data) { 39 | if (data.empty()) { 40 | return make_ready_future(std::move(data)); 41 | } else { 42 | count += std::count(data.begin(), data.end(), '\n'); 43 | // FIXME: last line without \n? 44 | return make_ready_future(); 45 | } 46 | } 47 | }; 48 | 49 | int main(int ac, char** av) { 50 | app_template app; 51 | namespace bpo = boost::program_options; 52 | app.add_positional_options({ 53 | { "file", bpo::value(), "File to process", 1 }, 54 | }); 55 | app.run_deprecated(ac, av, [&app] { 56 | auto fname = app.configuration()["file"].as(); 57 | engine().open_file_dma(fname, open_flags::ro).then([] (file f) { 58 | auto r = make_shared(std::move(f)); 59 | r->is.consume(*r).then([r] { 60 | print("%d lines\n", r->count); 61 | }); 62 | }).then_wrapped([] (future<> f) { 63 | try { 64 | f.get(); 65 | engine().exit(0); 66 | } catch (std::exception& ex) { 67 | std::cout << ex.what() << "\n"; 68 | engine().exit(1); 69 | } catch (...) { 70 | std::cout << "unknown exception\n"; 71 | engine().exit(0); 72 | } 73 | }); 74 | }); 75 | } 76 | 77 | -------------------------------------------------------------------------------- /doc/template.tex: -------------------------------------------------------------------------------- 1 | % The pandoc command line (see configure.py) can communicate variables to this 2 | % LaTeX skelaton, by using the "-V varname=value" command line parameter, and 3 | % there are also some builtin variables defined by other options. With such a 4 | % variable, we can use "$varname$" for the value, and $if(varname)$...$endif$ 5 | % for conditional code when this varname is defined. 6 | % 7 | % For an example of a more complete LaTeX template covering more of pandoc's 8 | % features, check out the example templates/default.latex in pandoc's 9 | % installation, or pandoc.org/demo/mytemplate.tex on their site. 10 | 11 | \documentclass[11]{article} 12 | \usepackage[a4paper, margin=1in]{geometry} 13 | \usepackage{lmodern} 14 | \usepackage{microtype} 15 | 16 | % Nice header with document's name and section name, and footer 17 | % with page number. 18 | \usepackage{fancyhdr} 19 | \pagestyle{fancy} 20 | \lhead{\itshape Seastar} 21 | \chead{} 22 | \rhead{\itshape{\nouppercase{\leftmark}}} 23 | \lfoot{} 24 | \cfoot{} 25 | \rfoot{\thepage} 26 | 27 | $if(highlighting-macros)$ 28 | $highlighting-macros$ 29 | $endif$ 30 | 31 | % Support links in PDF files 32 | \usepackage[]{hyperref} 33 | \hypersetup{breaklinks=true, 34 | bookmarks=true, % show bookmark bar (i.e, TOC sidebar) in PDF viewer 35 | pdfstartview=FitH, % cause Adobe Acrobat to do "fit to width" 36 | pdfauthor={ScyllaDB}, 37 | pdftitle={Asynchronous Programming with Seastar}, 38 | colorlinks=true, % if false, uses boxed links 39 | urlcolor=blue, % color of external links 40 | linkcolor=magenta % color of internal links (to other sections) 41 | } 42 | 43 | % Indentation went out of style with Disco music... It is especially 44 | % inconvenient in text which includes a lot of code snippets, etc, which 45 | % causes a lot of indents not preceeded by a text paragraph. So replace 46 | % the indentation with increased spacing between paragraphs. Note that this 47 | % also makes the TOC more spacious, I'm not sure it's a great idea. 48 | \setlength{\parindent}{0pt} 49 | \setlength{\parskip}{6pt plus 2pt minus 1pt} 50 | 51 | % Fancy-formatted title, but take the author list and date (if set) from the 52 | % preable in the markdown file. 53 | \title{\textbf{\fontsize{0.75cm}{1.5em}\selectfont Asynchronous Programming} \\ \textbf{\fontsize{0.75cm}{1.5em}\selectfont with} \\ \textbf{\fontsize{3cm}{1.5em}\selectfont Seastar}} 54 | \author{$for(author)$$author$$sep$ \and $endfor$} 55 | \date{$date$} 56 | 57 | \begin{document} 58 | \maketitle 59 | 60 | % Table of contents, before the body of the document. Make the TOC clickable, 61 | % with links to the respective sections, but override the internal link color 62 | % set above (magenta) by normal black color, because the entire TOC being in 63 | % a different color looks rather conspicuous. 64 | { 65 | \hypersetup{linkcolor=black} 66 | \tableofcontents 67 | } 68 | 69 | $body$ 70 | 71 | \end{document} 72 | -------------------------------------------------------------------------------- /core/unaligned.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #pragma once 23 | 24 | // The following unaligned_cast(p) is a portable replacement for 25 | // reinterpret_cast(p) which should be used every time address p 26 | // is not guaranteed to be properly aligned to alignof(T). 27 | // 28 | // On architectures like x86 and ARM, where unaligned access is allowed, 29 | // unaligned_cast will behave the same as reinterpret_cast and will generate 30 | // the same code. 31 | // 32 | // Certain architectures (e.g., MIPS) make it extremely slow or outright 33 | // forbidden to use ordinary machine instructions on a primitive type at an 34 | // unaligned addresses - e.g., access a uint32_t at an address which is not 35 | // a multiple of 4. Gcc's "undefined behavior sanitizer" (enabled in our debug 36 | // build) also catches such unaligned accesses and reports them as errors, 37 | // even when running on x86. 38 | // 39 | // Therefore, reinterpret_cast on an address which is not guaranteed 40 | // to be a multiple of 4 may generate extremely slow code or runtime errors, 41 | // and must be avoided. The compiler needs to be told about the unaligned 42 | // access, so it can generate reasonably-efficient code for the access 43 | // (in MIPS, this means generating two instructions "lwl" and "lwr", instead 44 | // of the one instruction "lw" which faults on unaligned/ access). The way to 45 | // tell the compiler this is with __attribute__((packed)). This will also 46 | // cause the sanitizer not to generate runtime alignment checks for this 47 | // access. 48 | 49 | template 50 | struct unaligned { 51 | T raw; 52 | unaligned() = default; 53 | unaligned(T x) : raw(x) {} 54 | unaligned& operator=(const T& x) { raw = x; return *this; } 55 | operator T() const { return raw; } 56 | } __attribute__((packed)); 57 | 58 | template 59 | inline auto unaligned_cast(F* p) { 60 | return reinterpret_cast>*>(p); 61 | } 62 | 63 | template 64 | inline auto unaligned_cast(const F* p) { 65 | return reinterpret_cast>*>(p); 66 | } 67 | -------------------------------------------------------------------------------- /core/xen/xenstore.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef XENSTORE_HH_ 23 | #define XENSTORE_HH_ 24 | 25 | #include 26 | 27 | extern "C" { 28 | #include 29 | } 30 | 31 | class xenstore { 32 | public: 33 | class xenstore_transaction { 34 | private: 35 | xenstore *_x; 36 | protected: 37 | xs_transaction_t _t = 0; 38 | public: 39 | explicit xenstore_transaction(xenstore *x) : _x(x) 40 | , _t(x->start_transaction()) {} 41 | explicit xenstore_transaction() {} 42 | 43 | ~xenstore_transaction() { if (_t) { _x->end_transaction(_t); } } 44 | 45 | xs_transaction_t t() { return _t; } 46 | friend class xenstore; 47 | }; 48 | 49 | protected: 50 | xs_transaction_t start_transaction(); 51 | void end_transaction(xs_transaction_t t); 52 | 53 | static xenstore_transaction _xs_null; // having it here simplify forward decls 54 | 55 | private: 56 | static xenstore *_instance; 57 | struct xs_handle *_h; 58 | explicit xenstore(); 59 | ~xenstore(); 60 | 61 | public: 62 | static xenstore *instance(); 63 | 64 | virtual void write(std::string path, std::string value, xenstore_transaction &t = _xs_null); 65 | virtual void remove(std::string path, xenstore_transaction &t = _xs_null); 66 | 67 | virtual std::string read(std::string path, xenstore_transaction &t = _xs_null); 68 | 69 | virtual std::list ls(std::string path, xenstore_transaction &t = _xs_null); 70 | template 71 | T read(std::string path, xenstore_transaction &t = _xs_null) { return boost::lexical_cast(read(path, t)); } 72 | template 73 | T read_or_default(std::string path, T deflt = T(), xenstore_transaction &t = _xs_null) { 74 | auto val = read(path, t); 75 | if (val.empty()) { 76 | return deflt; 77 | } else { 78 | return boost::lexical_cast(val); 79 | } 80 | } 81 | 82 | template 83 | void write(std::string path, T val, xenstore_transaction &t = _xs_null) { return write(path, std::to_string(val), t); } 84 | }; 85 | 86 | 87 | #endif /* XENSTORE_HH_ */ 88 | -------------------------------------------------------------------------------- /doc/template.css: -------------------------------------------------------------------------------- 1 | /* CSS style for Seastar's tutorial. 2 | * TODO: We also get some style for syntax highlighting inserted by our 3 | * use of "highlight-style tango" in configure.py. Perhaps we can insert 4 | * this style here too, for finer control. 5 | */ 6 | 7 | /* Some defaults */ 8 | body { 9 | color: #000000; 10 | background: #FFFFFF; 11 | font-size: 13pt; 12 | line-height: 1.10; 13 | font-family: arial, sans-serif; 14 | margin-left: 15pt; 15 | margin-right: 15pt; 16 | text-align: justify; 17 | } 18 | 19 | /* Pandoc puts the title, author and date, if any, in its own div id="header". 20 | */ 21 | div#header { 22 | border-top: 1px solid #aaa; 23 | border-bottom: 1px solid #aaa; 24 | background: #F0F0C0; 25 | margin: 10pt; 26 | margin-left: 10%; 27 | margin-right: 10%; 28 | } 29 | 30 | /* The title is in an h1.title, in the above div#header */ 31 | .title { 32 | color: #000000; 33 | margin: 5pt; 34 | text-align: center; 35 | font-family: serif; 36 | font-weight: bold; 37 | font-size: 32pt; 38 | } 39 | /* The author/date are h2.author and h3.date */ 40 | .author, .date { 41 | color: #000000; 42 | margin: 0pt; 43 | text-align: center; 44 | font-family: serif; 45 | font-weight: normal; 46 | font-size: 16pt; 47 | } 48 | 49 | /* table of contents is in div id="TOC" */ 50 | div#TOC { 51 | border-top: 1px solid #aaa; 52 | border-bottom: 1px solid #aaa; 53 | background: #F9F9F9; 54 | margin: 10pt; 55 | margin-left: 20%; 56 | margin-right: 20%; 57 | } 58 | 59 | 60 | h1, h2, h3, h4, h5, h6 { 61 | color: #EE3300; 62 | } 63 | 64 | a { 65 | text-decoration: none; 66 | } 67 | a:link, a:visited { 68 | color: #0000CC; 69 | } 70 | a:hover { 71 | color: #CC0000; 72 | text-decoration: underline; 73 | } 74 | 75 | 76 | /* code snippets. The "code" elements hold individual lines, the "pre" holds everything */ 77 | code, pre { 78 | background-color: #fdf7ee; 79 | background-color: #f8f8f8; 80 | 81 | /* BEGIN word wrap */ 82 | /* Need all the following to word wrap instead of scroll box */ 83 | /* This will override the overflow:auto if present */ 84 | white-space: pre-wrap; /* css-3 */ 85 | white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ 86 | white-space: -pre-wrap; /* Opera 4-6 */ 87 | white-space: -o-pre-wrap; /* Opera 7 */ 88 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 89 | /* END word wrap */ 90 | } 91 | 92 | pre { 93 | padding: 0.5em; 94 | border: 1px dotted #777; 95 | margin-left: 15pt; 96 | margin-right: 15pt; 97 | } 98 | 99 | /* Fix stuff for printing, in case somebody tries to print the HTML instead 100 | * of getting a PDF and printing that. For example, too big fonts and big 101 | * margins may be a waste of paper. 102 | * buttondown.css has a nice trick for replacing links with the actual text 103 | * of the URL - might be nice to copy it one day. 104 | */ 105 | @media print { 106 | body { font-size: 11pt; } 107 | a { color: black; background: transparent; } 108 | pre { border: 1px solid #aaa; } 109 | } 110 | -------------------------------------------------------------------------------- /tests/test_runner.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include 23 | 24 | #include "core/app-template.hh" 25 | #include "core/future-util.hh" 26 | #include "core/reactor.hh" 27 | #include "test_runner.hh" 28 | 29 | static test_runner instance; 30 | 31 | struct stop_execution : public std::exception {}; 32 | 33 | test_runner::~test_runner() { 34 | if (_thread) { 35 | _task.interrupt(stop_execution()); 36 | _thread->join(); 37 | } 38 | } 39 | 40 | void 41 | test_runner::start(int ac, char** av) { 42 | bool expected = false; 43 | if (!_started.compare_exchange_strong(expected, true, std::memory_order_acquire)) { 44 | return; 45 | } 46 | 47 | _thread = std::make_unique([this, ac, av]() mutable { 48 | app_template app; 49 | auto exit_code = app.run_deprecated(ac, av, [this] { 50 | do_until([this] { return _done; }, [this] { 51 | // this will block the reactor briefly, but we don't care 52 | try { 53 | auto func = _task.take(); 54 | return func(); 55 | } catch (const stop_execution&) { 56 | _done = true; 57 | engine().exit(0); 58 | return make_ready_future<>(); 59 | } 60 | }).or_terminate(); 61 | }); 62 | 63 | if (exit_code) { 64 | exit(exit_code); 65 | } 66 | }); 67 | } 68 | 69 | void 70 | test_runner::run_sync(std::function()> task) { 71 | exchanger> e; 72 | _task.give([task = std::move(task), &e] { 73 | try { 74 | return task().then_wrapped([&e](auto&& f) { 75 | try { 76 | f.get(); 77 | e.give({}); 78 | } catch (...) { 79 | e.give({std::current_exception()}); 80 | } 81 | }); 82 | } catch (...) { 83 | e.give({std::current_exception()}); 84 | return make_ready_future<>(); 85 | } 86 | }); 87 | auto maybe_exception = e.take(); 88 | if (maybe_exception) { 89 | std::rethrow_exception(*maybe_exception); 90 | } 91 | } 92 | 93 | test_runner& global_test_runner() { 94 | return instance; 95 | } 96 | -------------------------------------------------------------------------------- /core/fstream.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #pragma once 23 | 24 | // File <-> streams adapters 25 | // 26 | // Seastar files are block-based due to the reliance on DMA - you must read 27 | // on sector boundaries. The adapters in this file provide a byte stream 28 | // interface to files, while retaining the zero-copy characteristics of 29 | // seastar files. 30 | 31 | #include "file.hh" 32 | #include "iostream.hh" 33 | #include "shared_ptr.hh" 34 | 35 | 36 | /// Data structure describing options for opening a file input stream 37 | struct file_input_stream_options { 38 | uint64_t offset = 0; ///< File offset at which to start reading 39 | size_t buffer_size = 8192; ///< I/O buffer size 40 | unsigned read_ahead = 0; ///< Number of extra read-ahead operations 41 | }; 42 | 43 | // Create an input_stream for a given file, with the specified options. 44 | // Multiple fibers of execution (continuations) may safely open 45 | // multiple input streams concurrently for the same file. 46 | input_stream make_file_input_stream( 47 | file file, 48 | file_input_stream_options options = {}); 49 | 50 | // Create an input_stream for reading starting at a given position of the 51 | // given file. Multiple fibers of execution (continuations) may safely open 52 | // multiple input streams concurrently for the same file. 53 | input_stream make_file_input_stream( 54 | file file, uint64_t offset, 55 | uint64_t buffer_size = file_input_stream_options().buffer_size); 56 | 57 | struct file_output_stream_options { 58 | unsigned buffer_size = 8192; 59 | unsigned preallocation_size = 1024*1024; // 1MB 60 | unsigned write_behind = 1; ///< Number of buffers to write in parallel 61 | }; 62 | 63 | // Create an output_stream for writing starting at the position zero of a 64 | // newly created file. 65 | // NOTE: flush() should be the last thing to be called on a file output stream. 66 | output_stream make_file_output_stream( 67 | file file, 68 | uint64_t buffer_size = 8192); 69 | 70 | /// Create an output_stream for writing starting at the position zero of a 71 | /// newly created file. 72 | /// NOTE: flush() should be the last thing to be called on a file output stream. 73 | output_stream make_file_output_stream( 74 | file file, 75 | file_output_stream_options options); 76 | 77 | -------------------------------------------------------------------------------- /json/json_elements.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #include "json_elements.hh" 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | using namespace std; 29 | 30 | namespace json { 31 | 32 | /** 33 | * The json builder is a helper class 34 | * To help create a json object 35 | * 36 | */ 37 | class json_builder { 38 | public: 39 | json_builder() 40 | : first(true) { 41 | result << OPEN; 42 | } 43 | 44 | /** 45 | * add a name value to an object 46 | * @param name the name of the element 47 | * @param str the value already formated 48 | */ 49 | void add(const string& name, const string& str) { 50 | if (first) { 51 | first = false; 52 | } else { 53 | result << ", "; 54 | } 55 | result << '"' << name << "\": " << str; 56 | } 57 | 58 | /** 59 | * add a json element to the an object 60 | * @param element 61 | */ 62 | void add(json_base_element* element) { 63 | if (element == nullptr || element->_set == false) { 64 | return; 65 | } 66 | add(element->_name, element->to_string()); 67 | } 68 | 69 | /** 70 | * Get the string representation of the object 71 | * @return a string of accumulative object 72 | */ 73 | string as_json() { 74 | result << CLOSE; 75 | return result.str(); 76 | } 77 | 78 | private: 79 | static const string OPEN; 80 | static const string CLOSE; 81 | 82 | stringstream result; 83 | bool first; 84 | 85 | }; 86 | 87 | const string json_builder::OPEN("{"); 88 | const string json_builder::CLOSE("}"); 89 | 90 | void json_base::add(json_base_element* element, string name, bool mandatory) { 91 | element->_mandatory = mandatory; 92 | element->_name = name; 93 | _elements.push_back(element); 94 | } 95 | 96 | string json_base::to_json() const { 97 | json_builder res; 98 | for (auto i : _elements) { 99 | res.add(i); 100 | } 101 | return res.as_json(); 102 | } 103 | 104 | bool json_base::is_verify() const { 105 | for (auto i : _elements) { 106 | if (!i->is_verify()) { 107 | return false; 108 | } 109 | } 110 | return true; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /tests/thread_context_switch.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | /* 20 | * Copyright (C) 2015 Cloudius Systems, Ltd. 21 | */ 22 | 23 | #include 24 | #include "core/thread.hh" 25 | #include "core/semaphore.hh" 26 | #include "core/app-template.hh" 27 | #include "core/do_with.hh" 28 | #include "core/distributed.hh" 29 | #include "core/sleep.hh" 30 | 31 | using namespace seastar; 32 | using namespace std::chrono_literals; 33 | 34 | class context_switch_tester { 35 | uint64_t _switches{0}; 36 | semaphore _s1{0}; 37 | semaphore _s2{0}; 38 | bool _done1{false}; 39 | bool _done2{false}; 40 | thread _t1{[this] { main1(); }}; 41 | thread _t2{[this] { main2(); }}; 42 | private: 43 | void main1() { 44 | while (!_done1) { 45 | _s1.wait().get(); 46 | ++_switches; 47 | _s2.signal(); 48 | } 49 | _done2 = true; 50 | } 51 | void main2() { 52 | while (!_done2) { 53 | _s2.wait().get(); 54 | ++_switches; 55 | _s1.signal(); 56 | } 57 | } 58 | public: 59 | void begin_measurement() { 60 | _s1.signal(); 61 | } 62 | future measure() { 63 | _done1 = true; 64 | return _t1.join().then([this] { 65 | return _t2.join(); 66 | }).then([this] { 67 | return _switches; 68 | }); 69 | } 70 | future<> stop() { 71 | return make_ready_future<>(); 72 | } 73 | }; 74 | 75 | int main(int ac, char** av) { 76 | static const auto test_time = 5s; 77 | return app_template().run_deprecated(ac, av, [] { 78 | return do_with(distributed(), [] (distributed& dcst) { 79 | return dcst.start().then([&dcst] { 80 | return dcst.invoke_on_all(&context_switch_tester::begin_measurement); 81 | }).then([] { 82 | return sleep(test_time); 83 | }).then([&dcst] { 84 | return dcst.map_reduce0(std::mem_fn(&context_switch_tester::measure), uint64_t(), std::plus()); 85 | }).then([] (uint64_t switches) { 86 | switches /= smp::count; 87 | print("context switch time: %5.1f ns\n", 88 | double(std::chrono::duration_cast(test_time).count()) / switches); 89 | }).then([&dcst] { 90 | return dcst.stop(); 91 | }).then([] { 92 | engine_exit(0); 93 | }); 94 | }); 95 | }); 96 | } 97 | -------------------------------------------------------------------------------- /core/scattered_message.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #ifndef SCATTERED_MESSAGE_HH 23 | #define SCATTERED_MESSAGE_HH 24 | 25 | #include "core/deleter.hh" 26 | #include "core/temporary_buffer.hh" 27 | #include "net/packet.hh" 28 | #include "sstring.hh" 29 | #include 30 | #include 31 | #include 32 | 33 | template 34 | class scattered_message { 35 | private: 36 | using fragment = net::fragment; 37 | using packet = net::packet; 38 | using char_type = CharType; 39 | packet _p; 40 | public: 41 | scattered_message() {} 42 | scattered_message(scattered_message&&) = default; 43 | scattered_message(const scattered_message&) = delete; 44 | 45 | void append_static(const char_type* buf, size_t size) { 46 | if (size) { 47 | _p = packet(std::move(_p), fragment{(char_type*)buf, size}, deleter()); 48 | } 49 | } 50 | 51 | template 52 | void append_static(const char_type(&s)[N]) { 53 | append_static(s, N - 1); 54 | } 55 | 56 | void append_static(const char_type* s) { 57 | append_static(s, strlen(s)); 58 | } 59 | 60 | template 61 | void append_static(const basic_sstring& s) { 62 | append_static(s.begin(), s.size()); 63 | } 64 | 65 | void append_static(const std::experimental::string_view& s) { 66 | append_static(s.data(), s.size()); 67 | } 68 | 69 | template 70 | void append(basic_sstring s) { 71 | if (s.size()) { 72 | _p = packet(std::move(_p), std::move(s).release()); 73 | } 74 | } 75 | 76 | template 77 | void append(const basic_sstring& s, Callback callback) { 78 | if (s.size()) { 79 | _p = packet(std::move(_p), fragment{s.begin(), s.size()}, make_deleter(std::move(callback))); 80 | } 81 | } 82 | 83 | void reserve(int n_frags) { 84 | _p.reserve(n_frags); 85 | } 86 | 87 | packet release() && { 88 | return std::move(_p); 89 | } 90 | 91 | template 92 | void on_delete(Callback callback) { 93 | _p = packet(std::move(_p), make_deleter(std::move(callback))); 94 | } 95 | 96 | operator bool() const { 97 | return _p.len(); 98 | } 99 | 100 | size_t size() { 101 | return _p.len(); 102 | } 103 | }; 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /core/gate.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2014 Cloudius Systems 20 | */ 21 | 22 | #pragma once 23 | 24 | #include "future.hh" 25 | #include 26 | #include 27 | 28 | namespace seastar { 29 | 30 | /// \addtogroup fiber-module 31 | /// @{ 32 | 33 | namespace stdx = std::experimental; 34 | 35 | /// Exception thrown when a \ref gate object has been closed 36 | /// by the \ref gate::close() method. 37 | class gate_closed_exception : public std::exception { 38 | public: 39 | virtual const char* what() const noexcept override { 40 | return "gate closed"; 41 | } 42 | }; 43 | 44 | /// Facility to stop new requests, and to tell when existing requests are done. 45 | /// 46 | /// When stopping a service that serves asynchronous requests, we are faced with 47 | /// two problems: preventing new requests from coming in, and knowing when existing 48 | /// requests have completed. The \c gate class provides a solution. 49 | class gate { 50 | size_t _count = 0; 51 | stdx::optional> _stopped; 52 | public: 53 | /// Registers an in-progress request. 54 | /// 55 | /// If the gate is not closed, the request is registered. Otherwise, 56 | /// a \ref gate_closed_exception is thrown. 57 | void enter() { 58 | if (_stopped) { 59 | throw gate_closed_exception(); 60 | } 61 | ++_count; 62 | } 63 | /// Unregisters an in-progress request. 64 | /// 65 | /// If the gate is closed, and there are no more in-progress requests, 66 | /// the \ref closed() promise will be fulfilled. 67 | void leave() { 68 | --_count; 69 | if (!_count && _stopped) { 70 | _stopped->set_value(); 71 | } 72 | } 73 | /// Closes the gate. 74 | /// 75 | /// Future calls to \ref enter() will fail with an exception, and when 76 | /// all current requests call \ref leave(), the returned future will be 77 | /// made ready. 78 | future<> close() { 79 | _stopped = stdx::make_optional(promise<>()); 80 | if (!_count) { 81 | _stopped->set_value(); 82 | } 83 | return _stopped->get_future(); 84 | } 85 | }; 86 | 87 | /// Executes the function \c func making sure the gate \c g is properly entered 88 | /// and later on, properly left. 89 | /// 90 | /// \param func function to be executed 91 | /// \param g the gate. Caller must make sure that it outlives this function. 92 | /// \returns whatever \c func returns 93 | /// 94 | /// \relates gate 95 | template 96 | inline 97 | auto 98 | with_gate(gate& g, Func&& func) { 99 | g.enter(); 100 | return func().finally([&g] { g.leave(); }); 101 | } 102 | /// @} 103 | 104 | } 105 | -------------------------------------------------------------------------------- /tests/timertest.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2014 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include "core/app-template.hh" 23 | #include "core/reactor.hh" 24 | #include "core/print.hh" 25 | #include 26 | 27 | using namespace std::chrono_literals; 28 | 29 | #define BUG() do { \ 30 | std::cerr << "ERROR @ " << __FILE__ << ":" << __LINE__ << std::endl; \ 31 | throw std::runtime_error("test failed"); \ 32 | } while (0) 33 | 34 | #define OK() do { \ 35 | std::cerr << "OK @ " << __FILE__ << ":" << __LINE__ << std::endl; \ 36 | } while (0) 37 | 38 | template 39 | struct timer_test { 40 | timer t1; 41 | timer t2; 42 | timer t3; 43 | timer t4; 44 | timer t5; 45 | promise<> pr1; 46 | promise<> pr2; 47 | 48 | future<> run() { 49 | t1.set_callback([this] { 50 | OK(); 51 | print(" 500ms timer expired\n"); 52 | if (!t4.cancel()) { 53 | BUG(); 54 | } 55 | if (!t5.cancel()) { 56 | BUG(); 57 | } 58 | t5.arm(1100ms); 59 | }); 60 | t2.set_callback([this] { OK(); print(" 900ms timer expired\n"); }); 61 | t3.set_callback([this] { OK(); print("1000ms timer expired\n"); }); 62 | t4.set_callback([this] { OK(); print(" BAD cancelled timer expired\n"); }); 63 | t5.set_callback([this] { OK(); print("1600ms rearmed timer expired\n"); pr1.set_value(); }); 64 | 65 | t1.arm(500ms); 66 | t2.arm(900ms); 67 | t3.arm(1000ms); 68 | t4.arm(700ms); 69 | t5.arm(800ms); 70 | 71 | return pr1.get_future().then([this] { return test_timer_cancelling(); }); 72 | } 73 | 74 | future<> test_timer_cancelling() { 75 | timer& t1 = *new timer(); 76 | t1.set_callback([] { BUG(); }); 77 | t1.arm(100ms); 78 | t1.cancel(); 79 | 80 | t1.arm(100ms); 81 | t1.cancel(); 82 | 83 | t1.set_callback([this] { OK(); pr2.set_value(); }); 84 | t1.arm(100ms); 85 | return pr2.get_future().then([&t1] { delete &t1; }); 86 | } 87 | }; 88 | 89 | int main(int ac, char** av) { 90 | app_template app; 91 | timer_test t1; 92 | timer_test t2; 93 | return app.run_deprecated(ac, av, [&t1, &t2] { 94 | print("=== Start High res clock test\n"); 95 | t1.run().then([&t2] { 96 | print("=== Start Low res clock test\n"); 97 | return t2.run(); 98 | }).then([] { 99 | print("Done\n"); 100 | engine().exit(0); 101 | }); 102 | }); 103 | } 104 | -------------------------------------------------------------------------------- /tests/shared_ptr_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | /* 20 | * Copyright 2015 Cloudius Systems 21 | */ 22 | 23 | #define BOOST_TEST_DYN_LINK 24 | #define BOOST_TEST_MODULE core 25 | 26 | #include 27 | #include "core/shared_ptr.hh" 28 | 29 | struct expected_exception : public std::exception {}; 30 | 31 | struct A { 32 | static bool destroyed; 33 | A() { 34 | destroyed = false; 35 | } 36 | virtual ~A() { 37 | destroyed = true; 38 | } 39 | }; 40 | 41 | struct B { 42 | virtual void x() {} 43 | }; 44 | 45 | bool A::destroyed = false; 46 | 47 | BOOST_AUTO_TEST_CASE(explot_dynamic_cast_use_after_free_problem) { 48 | shared_ptr p = ::make_shared(); 49 | { 50 | auto p2 = dynamic_pointer_cast(p); 51 | BOOST_ASSERT(!p2); 52 | } 53 | BOOST_ASSERT(!A::destroyed); 54 | } 55 | 56 | class C : public enable_shared_from_this { 57 | public: 58 | shared_ptr dup() { return shared_from_this(); } 59 | shared_ptr get() const { return shared_from_this(); } 60 | }; 61 | 62 | BOOST_AUTO_TEST_CASE(test_const_ptr) { 63 | shared_ptr a = make_shared(); 64 | shared_ptr ca = a; 65 | BOOST_REQUIRE(ca == a); 66 | shared_ptr cca = ca->get(); 67 | BOOST_REQUIRE(cca == ca); 68 | } 69 | 70 | struct D {}; 71 | 72 | BOOST_AUTO_TEST_CASE(test_lw_const_ptr_1) { 73 | auto pd1 = make_lw_shared(D()); 74 | auto pd2 = make_lw_shared(D()); 75 | lw_shared_ptr pd3 = pd2; 76 | BOOST_REQUIRE(pd2 == pd3); 77 | } 78 | 79 | struct E : enable_lw_shared_from_this {}; 80 | 81 | BOOST_AUTO_TEST_CASE(test_lw_const_ptr_2) { 82 | auto pe1 = make_lw_shared(); 83 | auto pe2 = make_lw_shared(); 84 | lw_shared_ptr pe3 = pe2; 85 | BOOST_REQUIRE(pe2 == pe3); 86 | } 87 | 88 | struct F : enable_lw_shared_from_this { 89 | auto const_method() const { 90 | return shared_from_this(); 91 | } 92 | }; 93 | 94 | BOOST_AUTO_TEST_CASE(test_shared_from_this_called_on_const_object) { 95 | auto ptr = make_lw_shared(); 96 | ptr->const_method(); 97 | } 98 | 99 | BOOST_AUTO_TEST_CASE(test_exception_thrown_from_constructor_is_propagated) { 100 | struct X { 101 | X() { 102 | throw expected_exception(); 103 | } 104 | }; 105 | try { 106 | auto ptr = make_lw_shared(); 107 | BOOST_FAIL("Constructor should have thrown"); 108 | } catch (const expected_exception& e) { 109 | BOOST_MESSAGE("Expected exception caught"); 110 | } 111 | try { 112 | auto ptr = ::make_shared(); 113 | BOOST_FAIL("Constructor should have thrown"); 114 | } catch (const expected_exception& e) { 115 | BOOST_MESSAGE("Expected exception caught"); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /apps/httpd/main.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #include "http/httpd.hh" 23 | #include "http/handlers.hh" 24 | #include "http/function_handlers.hh" 25 | #include "http/file_handler.hh" 26 | #include "apps/httpd/demo.json.hh" 27 | #include "http/api_docs.hh" 28 | 29 | namespace bpo = boost::program_options; 30 | 31 | using namespace httpd; 32 | 33 | class handl : public httpd::handler_base { 34 | public: 35 | virtual future > handle(const sstring& path, 36 | std::unique_ptr req, std::unique_ptr rep) { 37 | rep->_content = "hello"; 38 | rep->done("html"); 39 | return make_ready_future>(std::move(rep)); 40 | } 41 | }; 42 | 43 | void set_routes(routes& r) { 44 | function_handler* h1 = new function_handler([](const_req req) { 45 | return "hello"; 46 | }); 47 | function_handler* h2 = new function_handler([](std::unique_ptr req) { 48 | return make_ready_future("json-future"); 49 | }); 50 | r.add(operation_type::GET, url("/"), h1); 51 | r.add(operation_type::GET, url("/jf"), h2); 52 | r.add(operation_type::GET, url("/file").remainder("path"), 53 | new directory_handler("/")); 54 | demo_json::hello_world.set(r, [] (const_req req) { 55 | demo_json::my_object obj; 56 | obj.var1 = req.param.at("var1"); 57 | obj.var2 = req.param.at("var2"); 58 | demo_json::ns_hello_world::query_enum v = demo_json::ns_hello_world::str2query_enum(req.query_parameters.at("query_enum")); 59 | // This demonstrate enum conversion 60 | obj.enum_var = v; 61 | return obj; 62 | }); 63 | } 64 | 65 | int main(int ac, char** av) { 66 | app_template app; 67 | app.add_options()("port", bpo::value()->default_value(10000), 68 | "HTTP Server port"); 69 | return app.run_deprecated(ac, av, [&] { 70 | auto&& config = app.configuration(); 71 | uint16_t port = config["port"].as(); 72 | auto server = new http_server_control(); 73 | auto rb = make_shared("apps/httpd/"); 74 | server->start().then([server] { 75 | return server->set_routes(set_routes); 76 | }).then([server, rb]{ 77 | return server->set_routes([rb](routes& r){rb->set_api_doc(r);}); 78 | }).then([server, rb]{ 79 | return server->set_routes([rb](routes& r) {rb->register_function(r, "demo", "hello world application");}); 80 | }).then([server, port] { 81 | return server->listen(port); 82 | }).then([server, port] { 83 | std::cout << "Seastar HTTP server listening on port " << port << " ...\n"; 84 | engine().at_exit([server] { 85 | return server->stop(); 86 | }); 87 | }); 88 | 89 | }); 90 | } 91 | -------------------------------------------------------------------------------- /http/matcher.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | #ifndef MATCHER_HH_ 23 | #define MATCHER_HH_ 24 | 25 | #include "common.hh" 26 | 27 | #include "core/sstring.hh" 28 | 29 | namespace httpd { 30 | 31 | /** 32 | * a base class for the url matching. 33 | * Each implementation check if the given url matches a criteria 34 | */ 35 | class matcher { 36 | public: 37 | 38 | virtual ~matcher() = default; 39 | 40 | /** 41 | * check if the given url matches the rule 42 | * @param url the url to check 43 | * @param ind the position to start from 44 | * @param fill the parameters hash 45 | * @return the end of of the matched part, or sstring::npos if not matched 46 | */ 47 | virtual size_t match(const sstring& url, size_t ind, parameters& param) = 0; 48 | }; 49 | 50 | /** 51 | * Check if the url match a parameter and fill the parameters object 52 | * 53 | * Note that a non empty url will always return true with the parameters 54 | * object filled 55 | * 56 | * Assume that the rule is /file/{path}/ and the param_matcher identify 57 | * the /{path} 58 | * 59 | * For all non empty values, match will return true. 60 | * If the entire url is /file/etc/hosts, and the part that is passed to 61 | * param_matcher is /etc/hosts, if entire_path is true, the match will be 62 | * '/etc/hosts' If entire_path is false, the match will be '/etc' 63 | */ 64 | class param_matcher : public matcher { 65 | public: 66 | /** 67 | * Constructor 68 | * @param name the name of the parameter, will be used as the key 69 | * in the parameters object 70 | * @param entire_path when set to true, the matched parameters will 71 | * include all the remaining url until the end of it. 72 | * when set to false the match will terminate at the next slash 73 | */ 74 | explicit param_matcher(const sstring& name, bool entire_path = false) 75 | : _name(name), _entire_path(entire_path) { 76 | } 77 | 78 | virtual size_t match(const sstring& url, size_t ind, parameters& param) 79 | override; 80 | private: 81 | sstring _name; 82 | bool _entire_path; 83 | }; 84 | 85 | /** 86 | * Check if the url match a predefine string. 87 | * 88 | * When parsing a match rule such as '/file/{path}' the str_match would parse 89 | * the '/file' part 90 | */ 91 | class str_matcher : public matcher { 92 | public: 93 | /** 94 | * Constructor 95 | * @param cmp the string to match 96 | */ 97 | explicit str_matcher(const sstring& cmp) 98 | : _cmp(cmp), _len(cmp.size()) { 99 | } 100 | 101 | virtual size_t match(const sstring& url, size_t ind, parameters& param) 102 | override; 103 | private: 104 | sstring _cmp; 105 | unsigned _len; 106 | }; 107 | 108 | } 109 | 110 | #endif /* MATCHER_HH_ */ 111 | -------------------------------------------------------------------------------- /http/http_response_parser.rl: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright (C) 2015 Cloudius Systems, Ltd. 20 | */ 21 | 22 | #include "core/ragel.hh" 23 | #include 24 | #include 25 | 26 | struct http_response { 27 | sstring _version; 28 | std::unordered_map _headers; 29 | }; 30 | 31 | %% machine http_response; 32 | 33 | %%{ 34 | 35 | access _fsm_; 36 | 37 | action mark { 38 | g.mark_start(p); 39 | } 40 | 41 | action store_version { 42 | _rsp->_version = str(); 43 | } 44 | 45 | action store_field_name { 46 | _field_name = str(); 47 | } 48 | 49 | action store_value { 50 | _value = str(); 51 | } 52 | 53 | action assign_field { 54 | _rsp->_headers[_field_name] = std::move(_value); 55 | } 56 | 57 | action extend_field { 58 | _rsp->_headers[_field_name] += sstring(" ") + std::move(_value); 59 | } 60 | 61 | action done { 62 | done = true; 63 | fbreak; 64 | } 65 | 66 | cr = '\r'; 67 | lf = '\n'; 68 | crlf = '\r\n'; 69 | tchar = alpha | digit | '-' | '!' | '#' | '$' | '%' | '&' | '\'' | '*' 70 | | '+' | '.' | '^' | '_' | '`' | '|' | '~'; 71 | 72 | sp = ' '; 73 | ht = '\t'; 74 | 75 | sp_ht = sp | ht; 76 | 77 | http_version = 'HTTP/' (digit '.' digit) >mark %store_version; 78 | 79 | field = tchar+ >mark %store_field_name; 80 | value = any* >mark %store_value; 81 | start_line = http_version space digit digit digit space (any - cr - lf)* crlf; 82 | header_1st = (field sp_ht* ':' value :> crlf) %assign_field; 83 | header_cont = (sp_ht+ value sp_ht* crlf) %extend_field; 84 | header = header_1st header_cont*; 85 | main := start_line header* :> (crlf @done); 86 | 87 | }%% 88 | 89 | class http_response_parser : public ragel_parser_base { 90 | %% write data nofinal noprefix; 91 | public: 92 | enum class state { 93 | error, 94 | eof, 95 | done, 96 | }; 97 | std::unique_ptr _rsp; 98 | sstring _field_name; 99 | sstring _value; 100 | state _state; 101 | public: 102 | void init() { 103 | init_base(); 104 | _rsp.reset(new http_response()); 105 | _state = state::eof; 106 | %% write init; 107 | } 108 | char* parse(char* p, char* pe, char* eof) { 109 | sstring_builder::guard g(_builder, p, pe); 110 | auto str = [this, &g, &p] { g.mark_end(p); return get_str(); }; 111 | bool done = false; 112 | if (p != pe) { 113 | _state = state::error; 114 | } 115 | %% write exec; 116 | if (!done) { 117 | p = nullptr; 118 | } else { 119 | _state = state::done; 120 | } 121 | return p; 122 | } 123 | auto get_parsed_response() { 124 | return std::move(_rsp); 125 | } 126 | bool eof() const { 127 | return _state == state::eof; 128 | } 129 | }; 130 | -------------------------------------------------------------------------------- /http/request.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is open source software, licensed to you under the terms 3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file 4 | * distributed with this work for additional information regarding copyright 5 | * ownership. You may not use this file except in compliance with the License. 6 | * 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | /* 19 | * Copyright 2015 Cloudius Systems 20 | */ 21 | 22 | // 23 | // request.hpp 24 | // ~~~~~~~~~~~ 25 | // 26 | // Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) 27 | // 28 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 29 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 30 | // 31 | #ifndef HTTP_REQUEST_HPP 32 | #define HTTP_REQUEST_HPP 33 | 34 | #include "core/sstring.hh" 35 | #include 36 | #include 37 | #include 38 | #include "common.hh" 39 | 40 | namespace httpd { 41 | class connection; 42 | 43 | /** 44 | * A request received from a client. 45 | */ 46 | struct request { 47 | enum class ctclass 48 | : char { 49 | other, multipart, app_x_www_urlencoded, 50 | }; 51 | 52 | sstring _method; 53 | sstring _url; 54 | sstring _version; 55 | int http_version_major; 56 | int http_version_minor; 57 | ctclass content_type_class; 58 | size_t content_length = 0; 59 | std::unordered_map _headers; 60 | std::unordered_map query_parameters; 61 | connection* connection_ptr; 62 | parameters param; 63 | sstring content; 64 | sstring protocol_name; 65 | 66 | /** 67 | * Search for the first header of a given name 68 | * @param name the header name 69 | * @return a pointer to the header value, if it exists or empty string 70 | */ 71 | sstring get_header(const sstring& name) const { 72 | auto res = _headers.find(name); 73 | if (res == _headers.end()) { 74 | return ""; 75 | } 76 | return res->second; 77 | } 78 | 79 | /** 80 | * Search for the first header of a given name 81 | * @param name the header name 82 | * @return a pointer to the header value, if it exists or empty string 83 | */ 84 | sstring get_query_param(const sstring& name) const { 85 | auto res = query_parameters.find(name); 86 | if (res == query_parameters.end()) { 87 | return ""; 88 | } 89 | return res->second; 90 | } 91 | 92 | /** 93 | * Get the request protocol name. Can be either "http" or "https". 94 | */ 95 | sstring get_protocol_name() const { 96 | return "http"; 97 | } 98 | 99 | /** 100 | * Get the request url. 101 | * @return the request url 102 | */ 103 | sstring get_url() const { 104 | return get_protocol_name() + "://" + get_header("Host") + _url; 105 | } 106 | 107 | bool is_multi_part() const { 108 | return content_type_class == ctclass::multipart; 109 | } 110 | 111 | bool is_form_post() const { 112 | return content_type_class == ctclass::app_x_www_urlencoded; 113 | } 114 | 115 | }; 116 | 117 | } // namespace httpd 118 | 119 | #endif // HTTP_REQUEST_HPP 120 | --------------------------------------------------------------------------------