From 2c4a43756ff76f84dc151088153266c81efda213 Mon Sep 17 00:00:00 2001 From: Mihai-Valentin DUMITRU <mihai.dumitru2201@upb.ro> Date: Sat, 24 Feb 2024 13:07:59 +0200 Subject: [PATCH] refactor the two link emulator labs --- common/Makefile | 8 + common/include/utils.h | 18 + common/link_emulator/.clang-format | 560 ++++++++++++++++++++++++ {lab3 => common}/link_emulator/Makefile | 4 +- common/link_emulator/lib.c | 117 +++++ common/link_emulator/lib.h | 25 ++ common/link_emulator/link.c | 465 ++++++++++++++++++++ {lab2 => common}/link_emulator/link.h | 9 +- common/link_emulator/queue.c | 66 +++ common/link_emulator/queue.h | 25 ++ common/run_experiment.sh | 24 + common/utils.c | 42 ++ lab2/Makefile | 16 +- lab2/common.h | 11 +- lab2/link_emulator | 1 + lab2/link_emulator.err | 0 lab2/link_emulator.out | 0 lab2/link_emulator/Makefile | 10 - lab2/link_emulator/lib.c | 105 ----- lab2/link_emulator/lib.h | 23 - lab2/link_emulator/link.c | 415 ------------------ lab2/link_emulator/queue.c | 61 --- lab2/link_emulator/queue.h | 25 -- lab2/recv | Bin 0 -> 23120 bytes lab2/recv.c | 17 +- lab2/run_experiment.sh | 24 +- lab2/send | Bin 0 -> 23072 bytes lab2/send.c | 12 +- lab3/Makefile | 16 +- lab3/link_emulator | 1 + lab3/link_emulator/lib.c | 103 ----- lab3/link_emulator/lib.h | 19 - lab3/link_emulator/link.c | 428 ------------------ lab3/link_emulator/link.h | 10 - lab3/link_emulator/queue.c | 61 --- lab3/link_emulator/queue.h | 25 -- lab3/recv.c | 14 +- lab3/run_experiment.sh | 24 +- lab3/send.c | 1 + 39 files changed, 1412 insertions(+), 1373 deletions(-) create mode 100644 common/Makefile create mode 100644 common/include/utils.h create mode 100644 common/link_emulator/.clang-format rename {lab3 => common}/link_emulator/Makefile (71%) create mode 100644 common/link_emulator/lib.c create mode 100644 common/link_emulator/lib.h create mode 100644 common/link_emulator/link.c rename {lab2 => common}/link_emulator/link.h (56%) create mode 100644 common/link_emulator/queue.c create mode 100644 common/link_emulator/queue.h create mode 100755 common/run_experiment.sh create mode 100644 common/utils.c create mode 120000 lab2/link_emulator create mode 100644 lab2/link_emulator.err create mode 100644 lab2/link_emulator.out delete mode 100644 lab2/link_emulator/Makefile delete mode 100644 lab2/link_emulator/lib.c delete mode 100644 lab2/link_emulator/lib.h delete mode 100644 lab2/link_emulator/link.c delete mode 100644 lab2/link_emulator/queue.c delete mode 100644 lab2/link_emulator/queue.h create mode 100755 lab2/recv mode change 100755 => 120000 lab2/run_experiment.sh create mode 100755 lab2/send create mode 120000 lab3/link_emulator delete mode 100644 lab3/link_emulator/lib.c delete mode 100644 lab3/link_emulator/lib.h delete mode 100644 lab3/link_emulator/link.c delete mode 100644 lab3/link_emulator/link.h delete mode 100644 lab3/link_emulator/queue.c delete mode 100644 lab3/link_emulator/queue.h mode change 100755 => 120000 lab3/run_experiment.sh diff --git a/common/Makefile b/common/Makefile new file mode 100644 index 0000000..fbedc82 --- /dev/null +++ b/common/Makefile @@ -0,0 +1,8 @@ +CFLAGS= -Wall -Werror -Wno-error=unused-variable + +all: utils.o + +clean: + -rm -f *.o + +.PHONY: all clean diff --git a/common/include/utils.h b/common/include/utils.h new file mode 100644 index 0000000..b276371 --- /dev/null +++ b/common/include/utils.h @@ -0,0 +1,18 @@ +#ifndef UTILS_H +#define UTILS_H + +#include <stdio.h> +#include <stdlib.h> + +void hex_dump(const void * addr, size_t size); + +#define DIE(condition, message, ...) \ +do { \ + if ((condition)) { \ + fprintf(stderr, "[(%s:%d)]: " # message "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ + perror(""); \ + exit(1); \ + } \ +} while (0) + +#endif /* UTILS_H */ diff --git a/common/link_emulator/.clang-format b/common/link_emulator/.clang-format new file mode 100644 index 0000000..fa95943 --- /dev/null +++ b/common/link_emulator/.clang-format @@ -0,0 +1,560 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# clang-format configuration file. Intended for clang-format >= 4. +# +# For more information, see: +# +# Documentation/process/clang-format.rst +# https://clang.llvm.org/docs/ClangFormat.html +# https://clang.llvm.org/docs/ClangFormatStyleOptions.html +# +--- +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +#AlignEscapedNewlines: Left # Unknown to clang-format-4.0 +AlignOperands: true +AlignTrailingComments: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + #AfterExternBlock: false # Unknown to clang-format-5.0 + BeforeCatch: false + BeforeElse: false + IndentBraces: false + #SplitEmptyFunction: true # Unknown to clang-format-4.0 + #SplitEmptyRecord: true # Unknown to clang-format-4.0 + #SplitEmptyNamespace: true # Unknown to clang-format-4.0 +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +#BreakBeforeInheritanceComma: false # Unknown to clang-format-4.0 +BreakBeforeTernaryOperators: false +BreakConstructorInitializersBeforeComma: false +#BreakConstructorInitializers: BeforeComma # Unknown to clang-format-4.0 +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: false +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +#CompactNamespaces: false # Unknown to clang-format-4.0 +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 8 +ContinuationIndentWidth: 8 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +#FixNamespaceComments: false # Unknown to clang-format-4.0 + +# Taken from: +# git grep -h '^#define [^[:space:]]*for_each[^[:space:]]*(' include/ \ +# | sed "s,^#define \([^[:space:]]*for_each[^[:space:]]*\)(.*$, - '\1'," \ +# | sort | uniq +ForEachMacros: + - 'apei_estatus_for_each_section' + - 'ata_for_each_dev' + - 'ata_for_each_link' + - '__ata_qc_for_each' + - 'ata_qc_for_each' + - 'ata_qc_for_each_raw' + - 'ata_qc_for_each_with_internal' + - 'ax25_for_each' + - 'ax25_uid_for_each' + - '__bio_for_each_bvec' + - 'bio_for_each_bvec' + - 'bio_for_each_bvec_all' + - 'bio_for_each_integrity_vec' + - '__bio_for_each_segment' + - 'bio_for_each_segment' + - 'bio_for_each_segment_all' + - 'bio_list_for_each' + - 'bip_for_each_vec' + - 'bitmap_for_each_clear_region' + - 'bitmap_for_each_set_region' + - 'blkg_for_each_descendant_post' + - 'blkg_for_each_descendant_pre' + - 'blk_queue_for_each_rl' + - 'bond_for_each_slave' + - 'bond_for_each_slave_rcu' + - 'bpf_for_each_spilled_reg' + - 'btree_for_each_safe128' + - 'btree_for_each_safe32' + - 'btree_for_each_safe64' + - 'btree_for_each_safel' + - 'card_for_each_dev' + - 'cgroup_taskset_for_each' + - 'cgroup_taskset_for_each_leader' + - 'cpufreq_for_each_entry' + - 'cpufreq_for_each_entry_idx' + - 'cpufreq_for_each_valid_entry' + - 'cpufreq_for_each_valid_entry_idx' + - 'css_for_each_child' + - 'css_for_each_descendant_post' + - 'css_for_each_descendant_pre' + - 'device_for_each_child_node' + - 'displayid_iter_for_each' + - 'dma_fence_chain_for_each' + - 'do_for_each_ftrace_op' + - 'drm_atomic_crtc_for_each_plane' + - 'drm_atomic_crtc_state_for_each_plane' + - 'drm_atomic_crtc_state_for_each_plane_state' + - 'drm_atomic_for_each_plane_damage' + - 'drm_client_for_each_connector_iter' + - 'drm_client_for_each_modeset' + - 'drm_connector_for_each_possible_encoder' + - 'drm_for_each_bridge_in_chain' + - 'drm_for_each_connector_iter' + - 'drm_for_each_crtc' + - 'drm_for_each_crtc_reverse' + - 'drm_for_each_encoder' + - 'drm_for_each_encoder_mask' + - 'drm_for_each_fb' + - 'drm_for_each_legacy_plane' + - 'drm_for_each_plane' + - 'drm_for_each_plane_mask' + - 'drm_for_each_privobj' + - 'drm_mm_for_each_hole' + - 'drm_mm_for_each_node' + - 'drm_mm_for_each_node_in_range' + - 'drm_mm_for_each_node_safe' + - 'flow_action_for_each' + - 'for_each_acpi_dev_match' + - 'for_each_active_dev_scope' + - 'for_each_active_drhd_unit' + - 'for_each_active_iommu' + - 'for_each_aggr_pgid' + - 'for_each_available_child_of_node' + - 'for_each_bio' + - 'for_each_board_func_rsrc' + - 'for_each_bvec' + - 'for_each_card_auxs' + - 'for_each_card_auxs_safe' + - 'for_each_card_components' + - 'for_each_card_dapms' + - 'for_each_card_pre_auxs' + - 'for_each_card_prelinks' + - 'for_each_card_rtds' + - 'for_each_card_rtds_safe' + - 'for_each_card_widgets' + - 'for_each_card_widgets_safe' + - 'for_each_cgroup_storage_type' + - 'for_each_child_of_node' + - 'for_each_clear_bit' + - 'for_each_clear_bit_from' + - 'for_each_cmsghdr' + - 'for_each_compatible_node' + - 'for_each_component_dais' + - 'for_each_component_dais_safe' + - 'for_each_comp_order' + - 'for_each_console' + - 'for_each_cpu' + - 'for_each_cpu_and' + - 'for_each_cpu_not' + - 'for_each_cpu_wrap' + - 'for_each_dapm_widgets' + - 'for_each_dev_addr' + - 'for_each_dev_scope' + - 'for_each_dma_cap_mask' + - 'for_each_dpcm_be' + - 'for_each_dpcm_be_rollback' + - 'for_each_dpcm_be_safe' + - 'for_each_dpcm_fe' + - 'for_each_drhd_unit' + - 'for_each_dss_dev' + - 'for_each_dtpm_table' + - 'for_each_efi_memory_desc' + - 'for_each_efi_memory_desc_in_map' + - 'for_each_element' + - 'for_each_element_extid' + - 'for_each_element_id' + - 'for_each_endpoint_of_node' + - 'for_each_evictable_lru' + - 'for_each_fib6_node_rt_rcu' + - 'for_each_fib6_walker_rt' + - 'for_each_free_mem_pfn_range_in_zone' + - 'for_each_free_mem_pfn_range_in_zone_from' + - 'for_each_free_mem_range' + - 'for_each_free_mem_range_reverse' + - 'for_each_func_rsrc' + - 'for_each_hstate' + - 'for_each_if' + - 'for_each_iommu' + - 'for_each_ip_tunnel_rcu' + - 'for_each_irq_nr' + - 'for_each_link_codecs' + - 'for_each_link_cpus' + - 'for_each_link_platforms' + - 'for_each_lru' + - 'for_each_matching_node' + - 'for_each_matching_node_and_match' + - 'for_each_member' + - 'for_each_memcg_cache_index' + - 'for_each_mem_pfn_range' + - '__for_each_mem_range' + - 'for_each_mem_range' + - '__for_each_mem_range_rev' + - 'for_each_mem_range_rev' + - 'for_each_mem_region' + - 'for_each_migratetype_order' + - 'for_each_msi_entry' + - 'for_each_msi_entry_safe' + - 'for_each_net' + - 'for_each_net_continue_reverse' + - 'for_each_netdev' + - 'for_each_netdev_continue' + - 'for_each_netdev_continue_rcu' + - 'for_each_netdev_continue_reverse' + - 'for_each_netdev_feature' + - 'for_each_netdev_in_bond_rcu' + - 'for_each_netdev_rcu' + - 'for_each_netdev_reverse' + - 'for_each_netdev_safe' + - 'for_each_net_rcu' + - 'for_each_new_connector_in_state' + - 'for_each_new_crtc_in_state' + - 'for_each_new_mst_mgr_in_state' + - 'for_each_new_plane_in_state' + - 'for_each_new_private_obj_in_state' + - 'for_each_node' + - 'for_each_node_by_name' + - 'for_each_node_by_type' + - 'for_each_node_mask' + - 'for_each_node_state' + - 'for_each_node_with_cpus' + - 'for_each_node_with_property' + - 'for_each_nonreserved_multicast_dest_pgid' + - 'for_each_of_allnodes' + - 'for_each_of_allnodes_from' + - 'for_each_of_cpu_node' + - 'for_each_of_pci_range' + - 'for_each_old_connector_in_state' + - 'for_each_old_crtc_in_state' + - 'for_each_old_mst_mgr_in_state' + - 'for_each_oldnew_connector_in_state' + - 'for_each_oldnew_crtc_in_state' + - 'for_each_oldnew_mst_mgr_in_state' + - 'for_each_oldnew_plane_in_state' + - 'for_each_oldnew_plane_in_state_reverse' + - 'for_each_oldnew_private_obj_in_state' + - 'for_each_old_plane_in_state' + - 'for_each_old_private_obj_in_state' + - 'for_each_online_cpu' + - 'for_each_online_node' + - 'for_each_online_pgdat' + - 'for_each_pci_bridge' + - 'for_each_pci_dev' + - 'for_each_pci_msi_entry' + - 'for_each_pcm_streams' + - 'for_each_physmem_range' + - 'for_each_populated_zone' + - 'for_each_possible_cpu' + - 'for_each_present_cpu' + - 'for_each_prime_number' + - 'for_each_prime_number_from' + - 'for_each_process' + - 'for_each_process_thread' + - 'for_each_prop_codec_conf' + - 'for_each_prop_dai_codec' + - 'for_each_prop_dai_cpu' + - 'for_each_prop_dlc_codecs' + - 'for_each_prop_dlc_cpus' + - 'for_each_prop_dlc_platforms' + - 'for_each_property_of_node' + - 'for_each_registered_fb' + - 'for_each_requested_gpio' + - 'for_each_requested_gpio_in_range' + - 'for_each_reserved_mem_range' + - 'for_each_reserved_mem_region' + - 'for_each_rtd_codec_dais' + - 'for_each_rtd_components' + - 'for_each_rtd_cpu_dais' + - 'for_each_rtd_dais' + - 'for_each_set_bit' + - 'for_each_set_bit_from' + - 'for_each_set_clump8' + - 'for_each_sg' + - 'for_each_sg_dma_page' + - 'for_each_sg_page' + - 'for_each_sgtable_dma_page' + - 'for_each_sgtable_dma_sg' + - 'for_each_sgtable_page' + - 'for_each_sgtable_sg' + - 'for_each_sibling_event' + - 'for_each_subelement' + - 'for_each_subelement_extid' + - 'for_each_subelement_id' + - '__for_each_thread' + - 'for_each_thread' + - 'for_each_unicast_dest_pgid' + - 'for_each_vsi' + - 'for_each_wakeup_source' + - 'for_each_zone' + - 'for_each_zone_zonelist' + - 'for_each_zone_zonelist_nodemask' + - 'fwnode_for_each_available_child_node' + - 'fwnode_for_each_child_node' + - 'fwnode_graph_for_each_endpoint' + - 'gadget_for_each_ep' + - 'genradix_for_each' + - 'genradix_for_each_from' + - 'hash_for_each' + - 'hash_for_each_possible' + - 'hash_for_each_possible_rcu' + - 'hash_for_each_possible_rcu_notrace' + - 'hash_for_each_possible_safe' + - 'hash_for_each_rcu' + - 'hash_for_each_safe' + - 'hctx_for_each_ctx' + - 'hlist_bl_for_each_entry' + - 'hlist_bl_for_each_entry_rcu' + - 'hlist_bl_for_each_entry_safe' + - 'hlist_for_each' + - 'hlist_for_each_entry' + - 'hlist_for_each_entry_continue' + - 'hlist_for_each_entry_continue_rcu' + - 'hlist_for_each_entry_continue_rcu_bh' + - 'hlist_for_each_entry_from' + - 'hlist_for_each_entry_from_rcu' + - 'hlist_for_each_entry_rcu' + - 'hlist_for_each_entry_rcu_bh' + - 'hlist_for_each_entry_rcu_notrace' + - 'hlist_for_each_entry_safe' + - 'hlist_for_each_entry_srcu' + - '__hlist_for_each_rcu' + - 'hlist_for_each_safe' + - 'hlist_nulls_for_each_entry' + - 'hlist_nulls_for_each_entry_from' + - 'hlist_nulls_for_each_entry_rcu' + - 'hlist_nulls_for_each_entry_safe' + - 'i3c_bus_for_each_i2cdev' + - 'i3c_bus_for_each_i3cdev' + - 'ide_host_for_each_port' + - 'ide_port_for_each_dev' + - 'ide_port_for_each_present_dev' + - 'idr_for_each_entry' + - 'idr_for_each_entry_continue' + - 'idr_for_each_entry_continue_ul' + - 'idr_for_each_entry_ul' + - 'in_dev_for_each_ifa_rcu' + - 'in_dev_for_each_ifa_rtnl' + - 'inet_bind_bucket_for_each' + - 'inet_lhash2_for_each_icsk_rcu' + - 'key_for_each' + - 'key_for_each_safe' + - 'klp_for_each_func' + - 'klp_for_each_func_safe' + - 'klp_for_each_func_static' + - 'klp_for_each_object' + - 'klp_for_each_object_safe' + - 'klp_for_each_object_static' + - 'kunit_suite_for_each_test_case' + - 'kvm_for_each_memslot' + - 'kvm_for_each_vcpu' + - 'list_for_each' + - 'list_for_each_codec' + - 'list_for_each_codec_safe' + - 'list_for_each_continue' + - 'list_for_each_entry' + - 'list_for_each_entry_continue' + - 'list_for_each_entry_continue_rcu' + - 'list_for_each_entry_continue_reverse' + - 'list_for_each_entry_from' + - 'list_for_each_entry_from_rcu' + - 'list_for_each_entry_from_reverse' + - 'list_for_each_entry_lockless' + - 'list_for_each_entry_rcu' + - 'list_for_each_entry_reverse' + - 'list_for_each_entry_safe' + - 'list_for_each_entry_safe_continue' + - 'list_for_each_entry_safe_from' + - 'list_for_each_entry_safe_reverse' + - 'list_for_each_entry_srcu' + - 'list_for_each_prev' + - 'list_for_each_prev_safe' + - 'list_for_each_safe' + - 'llist_for_each' + - 'llist_for_each_entry' + - 'llist_for_each_entry_safe' + - 'llist_for_each_safe' + - 'mci_for_each_dimm' + - 'media_device_for_each_entity' + - 'media_device_for_each_intf' + - 'media_device_for_each_link' + - 'media_device_for_each_pad' + - 'nanddev_io_for_each_page' + - 'netdev_for_each_lower_dev' + - 'netdev_for_each_lower_private' + - 'netdev_for_each_lower_private_rcu' + - 'netdev_for_each_mc_addr' + - 'netdev_for_each_uc_addr' + - 'netdev_for_each_upper_dev_rcu' + - 'netdev_hw_addr_list_for_each' + - 'nft_rule_for_each_expr' + - 'nla_for_each_attr' + - 'nla_for_each_nested' + - 'nlmsg_for_each_attr' + - 'nlmsg_for_each_msg' + - 'nr_neigh_for_each' + - 'nr_neigh_for_each_safe' + - 'nr_node_for_each' + - 'nr_node_for_each_safe' + - 'of_for_each_phandle' + - 'of_property_for_each_string' + - 'of_property_for_each_u32' + - 'pci_bus_for_each_resource' + - 'pcl_for_each_chunk' + - 'pcl_for_each_segment' + - 'pcm_for_each_format' + - 'ping_portaddr_for_each_entry' + - 'plist_for_each' + - 'plist_for_each_continue' + - 'plist_for_each_entry' + - 'plist_for_each_entry_continue' + - 'plist_for_each_entry_safe' + - 'plist_for_each_safe' + - 'pnp_for_each_card' + - 'pnp_for_each_dev' + - 'protocol_for_each_card' + - 'protocol_for_each_dev' + - 'queue_for_each_hw_ctx' + - 'radix_tree_for_each_slot' + - 'radix_tree_for_each_tagged' + - 'rb_for_each' + - 'rbtree_postorder_for_each_entry_safe' + - 'rdma_for_each_block' + - 'rdma_for_each_port' + - 'rdma_umem_for_each_dma_block' + - 'resource_list_for_each_entry' + - 'resource_list_for_each_entry_safe' + - 'rhl_for_each_entry_rcu' + - 'rhl_for_each_rcu' + - 'rht_for_each' + - 'rht_for_each_entry' + - 'rht_for_each_entry_from' + - 'rht_for_each_entry_rcu' + - 'rht_for_each_entry_rcu_from' + - 'rht_for_each_entry_safe' + - 'rht_for_each_from' + - 'rht_for_each_rcu' + - 'rht_for_each_rcu_from' + - '__rq_for_each_bio' + - 'rq_for_each_bvec' + - 'rq_for_each_segment' + - 'scsi_for_each_prot_sg' + - 'scsi_for_each_sg' + - 'sctp_for_each_hentry' + - 'sctp_skb_for_each' + - 'shdma_for_each_chan' + - '__shost_for_each_device' + - 'shost_for_each_device' + - 'sk_for_each' + - 'sk_for_each_bound' + - 'sk_for_each_entry_offset_rcu' + - 'sk_for_each_from' + - 'sk_for_each_rcu' + - 'sk_for_each_safe' + - 'sk_nulls_for_each' + - 'sk_nulls_for_each_from' + - 'sk_nulls_for_each_rcu' + - 'snd_array_for_each' + - 'snd_pcm_group_for_each_entry' + - 'snd_soc_dapm_widget_for_each_path' + - 'snd_soc_dapm_widget_for_each_path_safe' + - 'snd_soc_dapm_widget_for_each_sink_path' + - 'snd_soc_dapm_widget_for_each_source_path' + - 'tb_property_for_each' + - 'tcf_exts_for_each_action' + - 'udp_portaddr_for_each_entry' + - 'udp_portaddr_for_each_entry_rcu' + - 'usb_hub_for_each_child' + - 'v4l2_device_for_each_subdev' + - 'v4l2_m2m_for_each_dst_buf' + - 'v4l2_m2m_for_each_dst_buf_safe' + - 'v4l2_m2m_for_each_src_buf' + - 'v4l2_m2m_for_each_src_buf_safe' + - 'virtio_device_for_each_vq' + - 'while_for_each_ftrace_op' + - 'xa_for_each' + - 'xa_for_each_marked' + - 'xa_for_each_range' + - 'xa_for_each_start' + - 'xas_for_each' + - 'xas_for_each_conflict' + - 'xas_for_each_marked' + - 'xbc_array_for_each_value' + - 'xbc_for_each_key_value' + - 'xbc_node_for_each_array_value' + - 'xbc_node_for_each_child' + - 'xbc_node_for_each_key_value' + - 'zorro_for_each_dev' + +#IncludeBlocks: Preserve # Unknown to clang-format-5.0 +IncludeCategories: + - Regex: '.*' + Priority: 1 +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: false +#IndentPPDirectives: None # Unknown to clang-format-5.0 +IndentWidth: 8 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +#ObjCBinPackProtocolList: Auto # Unknown to clang-format-5.0 +ObjCBlockIndentWidth: 8 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true + +# Taken from git's rules +#PenaltyBreakAssignment: 10 # Unknown to clang-format-4.0 +PenaltyBreakBeforeFirstCallParameter: 30 +PenaltyBreakComment: 10 +PenaltyBreakFirstLessLess: 0 +PenaltyBreakString: 10 +PenaltyExcessCharacter: 100 +PenaltyReturnTypeOnItsOwnLine: 60 + +PointerAlignment: Right +ReflowComments: false +SortIncludes: false +#SortUsingDeclarations: false # Unknown to clang-format-4.0 +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +#SpaceBeforeCtorInitializerColon: true # Unknown to clang-format-5.0 +#SpaceBeforeInheritanceColon: true # Unknown to clang-format-5.0 +SpaceBeforeParens: ControlStatements +#SpaceBeforeRangeBasedForLoopColon: true # Unknown to clang-format-5.0 +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp03 +TabWidth: 8 +UseTab: Always +... diff --git a/lab3/link_emulator/Makefile b/common/link_emulator/Makefile similarity index 71% rename from lab3/link_emulator/Makefile rename to common/link_emulator/Makefile index bc25fa3..9503a5a 100644 --- a/lab3/link_emulator/Makefile +++ b/common/link_emulator/Makefile @@ -3,8 +3,8 @@ all: link lib.o link: link.o queue.o gcc -g link.o queue.o -o link -pthread -.c.o: - gcc -Wall -g -c $? -pthread +.c.o: + gcc -Wall -g -c $? -pthread -I../ clean: rm -f *.o link diff --git a/common/link_emulator/lib.c b/common/link_emulator/lib.c new file mode 100644 index 0000000..49181d2 --- /dev/null +++ b/common/link_emulator/lib.c @@ -0,0 +1,117 @@ +#include "lib.h" +#include "include/utils.h" +#include <arpa/inet.h> +#include <poll.h> +#include <netinet/in.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <unistd.h> +#include <string.h> + +struct sockaddr_in addr_local, addr_remote; +int s; +struct pollfd fds[1]; + +void set_local_port(int port) +{ + memset((char *) &addr_local, 0, sizeof(addr_local)); + addr_local.sin_family = AF_INET; + addr_local.sin_port = htons(port); + addr_local.sin_addr.s_addr = htonl(INADDR_ANY); +} + +void set_remote(char* ip, int port) +{ + memset((char *) &addr_remote, 0, sizeof(addr_remote)); + addr_remote.sin_family = AF_INET; + addr_remote.sin_port = htons(port); + int res = inet_aton(ip, &addr_remote.sin_addr); + DIE(res == 0, "inet_aton failed\n"); +} + +void init(char* remote, int REMOTE_PORT) +{ + s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + DIE(s == -1, "Error creating socket"); + + set_local_port(0); + set_remote(remote, REMOTE_PORT); + + int res = bind(s, (struct sockaddr*)&addr_local, sizeof(addr_local)); + DIE(res == -1, "Failed to bind"); + + fds[0].fd = s; + fds[0].events = POLLIN; + + msg m; + send_message(&m); +} + +int send_message(const msg *m) +{ + return sendto(s, m, sizeof(msg), 0,(struct sockaddr*) &addr_remote, + sizeof(addr_remote)); +} + +int link_send(void *buf, int len) +{ + msg m; + + memcpy(m.payload, buf, len); + m.len = len; + + return send_message(&m); +} + +int recv_message(msg *ret) +{ + return recvfrom(s, ret, sizeof(msg), 0, NULL, NULL); +} + +int link_recv(void *buf, int len) +{ + msg m; + recv_message(&m); + int r = m.len < len ? m.len : len; + memcpy(buf, m.payload, r); + return r; +} + +//timeout in millis +int recv_message_timeout(msg *m, int timeout) +{ + int ret = poll(fds, 1, timeout); + + if (ret > 0) { + if (fds[0].revents & POLLIN) + return recv_message(m); + } + + return -1; +} + +int link_recv_timeout(void *buf, int len, int timeout) +{ + msg m; + recv_message_timeout(&m, timeout); + int r = m.len < len ? m.len : len; + memcpy(buf, m.payload, r); + return r; +} + +int send_byte(uint8_t byte) { + printf("Sending byte %1$c (0x%1$02x)\n", byte); + return link_send(&byte, sizeof(byte)); +} + +uint8_t recv_byte() { + int ret; + uint8_t byte; + ret = link_recv_timeout(&byte, sizeof(byte), 100000); + if (ret < 0) + byte = rand() % 128; + + return byte; +} diff --git a/common/link_emulator/lib.h b/common/link_emulator/lib.h new file mode 100644 index 0000000..5d4fca6 --- /dev/null +++ b/common/link_emulator/lib.h @@ -0,0 +1,25 @@ +#ifndef _LIB_H_ +#define _LIB_H_ + +#include <stddef.h> +#include <stdint.h> + +#define MAX_LEN 1400 + +typedef struct { + int len; + char payload[MAX_LEN]; +} msg; + +void init(char* remote, int remote_port); +void set_local_port(int port); +void set_remote(char* ip, int port); +int send_message(const msg *t); +int recv_message(msg* r); +int recv_message_timeout(msg *m, int timeout); +int link_send(void *buf, int len); +int link_recv(void *buf, int len); +int send_byte(uint8_t b); +uint8_t recv_byte(void); + +#endif /* _LIB_H_ */ diff --git a/common/link_emulator/link.c b/common/link_emulator/link.c new file mode 100644 index 0000000..a714173 --- /dev/null +++ b/common/link_emulator/link.c @@ -0,0 +1,465 @@ +#include <arpa/inet.h> +#include <assert.h> +#include <netinet/in.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <sys/types.h> +#include <unistd.h> +//#include <asm/param.h> +#include "link.h" +#include "queue.h" +#include "include/utils.h" + +#define DEBUG 0 + +int BUFFER_SIZE = 1000; + +int serialization_delay = 1000; +int delay = 1000; +int loss = 0; +int corrupt = 0; +int corrupt2 = 0; +int reorder = 0; + +#define CHANNEL_BUSY 1 +#define CHANNEL_IDLE 0 + +#define LOCAL_PORT1 10000 +#define LOCAL_PORT2 10001 + +pthread_mutex_t buffer_lock = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t buffer_cond = PTHREAD_COND_INITIALIZER; +queue *buffer; + +struct sockaddr_in local_addr1, remote_addr1; +struct sockaddr_in local_addr2, remote_addr2; + +int s1, s2; +socklen_t sz; + +// 1 if a message was received on this link +int link_up1 = 0; +int link_up2 = 0; + +void init_sockets() +{ + /*LOCAL ADDRESSES*/ + + memset((char *)&local_addr1, 0, sizeof(local_addr1)); + local_addr1.sin_family = AF_INET; + local_addr1.sin_port = htons(LOCAL_PORT1); + local_addr1.sin_addr.s_addr = htonl(INADDR_ANY); + + memset((char *)&local_addr2, 0, sizeof(local_addr2)); + local_addr2.sin_family = AF_INET; + local_addr2.sin_port = htons(LOCAL_PORT2); + local_addr2.sin_addr.s_addr = htonl(INADDR_ANY); + + s1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + DIE(s1 == -1, "Error creating socket"); + + // now bind + int res = bind(s1, (struct sockaddr *)&local_addr1, sizeof(local_addr1)); + DIE(res == -1, "Failed to bind s1"); + + s2 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + DIE(s2 == -1, "Error creating socket 2"); + + res = bind(s2, (struct sockaddr *)&local_addr2, sizeof(local_addr2)); + DIE(res == -1, "Failed to bind s2"); +} + +int send_message1(const msg *m) +{ + if (!link_up1) { + printf("Trying to send a message but remote peer is not connected on my " + "port %d\n", + LOCAL_PORT1); + } + return sendto(s1, m, sizeof(msg), 0, (struct sockaddr *)&remote_addr1, + sizeof(remote_addr1)); +} + +msg *receive_message1() +{ + msg *ret; + +a: + ret = (msg *)malloc(sizeof(msg)); + DIE(!ret, "malloc"); + + if (!link_up1) { + sz = sizeof(remote_addr1); + if (recvfrom(s1, ret, sizeof(msg), 0, + (struct sockaddr *)&remote_addr1, &sz) == -1) { + free(ret); + return NULL; + } + + link_up1 = 1; + +#if DEBUG + printf("Link 1 is up, remote addr is %s port %d\n", + inet_ntoa(remote_addr1.sin_addr), + ntohs(remote_addr1.sin_port)); +#endif + + free(ret); + goto a; + } else if (recvfrom(s1, ret, sizeof(msg), 0, NULL, NULL) == -1) { + free(ret); + return NULL; + } + return ret; +} + +int send_message2(const msg *m) +{ + if (!link_up2) { + printf("Trying to send a message but remote peer is not connected on my " + "port %d\n", + LOCAL_PORT2); + } + return sendto(s2, m, sizeof(msg), 0, (struct sockaddr *)&remote_addr2, + sizeof(remote_addr2)); +} + +msg *receive_message2() +{ + msg *ret; + +a: + ret = (msg *)malloc(sizeof(msg)); + DIE(!ret, "malloc"); + + if (!link_up2) { + sz = sizeof(remote_addr2); + if (recvfrom(s2, ret, sizeof(msg), 0, + (struct sockaddr *)&remote_addr2, &sz) == -1) { + free(ret); + return NULL; + } + link_up2 = 1; + +#if DEBUG + printf("Link 2 is up, remote addr is %s port %d\n", + inet_ntoa(remote_addr2.sin_addr), + ntohs(remote_addr2.sin_port)); +#endif + + free(ret); + goto a; + } else if (recvfrom(s2, ret, sizeof(msg), 0, NULL, NULL) == -1) { + free(ret); + return NULL; + } + + return ret; +} + +unsigned long long now() +{ + struct timeval b; + gettimeofday(&b, NULL); + return (unsigned long long)b.tv_sec * 1000000 + b.tv_usec; +} + +void *link_scheduler(void *argument) +{ + msg_in_flight *mif; + queue *in_flight = create_queue(); + long long idle_time = 0; + long long crt_time, wait_time_idle, wait_time_send; + int stuff; + + while (1) { + crt_time = now(); + +#if DEBUG + printf("In flight size %d at %lld\n", in_flight->size, + crt_time); +#endif + + while (in_flight->size > 0) { + msg_in_flight *last = + (msg_in_flight *)in_flight->last->crt; + if (crt_time < last->finish_time) { + break; + } + + // else send first packet on the wire + mif = (msg_in_flight *)dequeue(in_flight); + DIE(!mif, "Error in deque: expecting non null msg!"); + if (send_message2(mif->m) <= 0) + perror("SNDMSG2"); + +#if DEBUG + printf("Sending message\n"); +#endif + + free(mif->m); + free(mif); + mif = NULL; + } + + pthread_mutex_lock(&buffer_lock); + stuff = buffer->size > 0; + pthread_mutex_unlock(&buffer_lock); + +#if DEBUG + printf("Stuff is %d\n", stuff); +#endif + + wait_time_send = wait_time_idle = 0; + + // crt_time = now(); + + // now see if we can put stuff in flight + if (stuff && crt_time >= idle_time) { + idle_time = crt_time + serialization_delay; + + mif = (msg_in_flight *)malloc(sizeof(msg_in_flight)); + assert(mif); + + pthread_mutex_lock(&buffer_lock); + + if (rand() % 100 < reorder && buffer->size > 1) { + msg *m = (msg *)dequeue(buffer); + enqueue(buffer,m); + } + + mif->m = (msg *)dequeue(buffer); + pthread_mutex_unlock(&buffer_lock); + + assert(mif->m); + mif->finish_time = + crt_time + serialization_delay + delay; + + // send message here from buffer to link + enqueue(in_flight, mif); + +#if DEBUG + printf("Enquing message\n"); +#endif + } + wait_time_idle = idle_time - crt_time; + + if (in_flight->size > 0) { + msg_in_flight *last = + (msg_in_flight *)in_flight->last->crt; + wait_time_send = last->finish_time - crt_time; + } + + if (wait_time_idle > 0 || wait_time_send > 0) { + long long wait_time = 0; + if (wait_time_idle > 0) + wait_time = wait_time_idle; + if (wait_time_send > 0 && wait_time_send < wait_time) + wait_time = wait_time_send; + + // printf("Sleeping %lld\n", wait_time); + usleep(wait_time); + } else { + pthread_mutex_lock(&buffer_lock); + assert(!buffer->size); +#if DEBUG + printf("Waiting on cond\n"); +#endif + pthread_cond_wait(&buffer_cond, &buffer_lock); + pthread_mutex_unlock(&buffer_lock); + } + } + + return NULL; +} + +void *run_forwarding(void *param) +{ + msg *m; + + while (1) { + int overflow; + m = receive_message1(); + DIE(m == NULL, "Read error"); + + // check queue space + pthread_mutex_lock(&buffer_lock); + overflow = buffer->size >= BUFFER_SIZE; + pthread_mutex_unlock(&buffer_lock); + + if (overflow || (rand() % 100) < loss) { + // just drop message + free(m); + printf("Dropped packet\n"); + } else { + if (rand() % 100 < corrupt) { + // flip a random bit in a randomly chosen byte + // of the payload + int random_byte = rand() % m->len; + int random_bit = rand(); + m->payload[random_byte] ^= 1 + << (random_bit % 8); + + if (rand() % 100 < corrupt2) { + // flip a second bit in the same byte + int random_bit2; + do { + random_bit2 = rand(); + } while (random_bit2 == random_bit); + m->payload[random_byte] ^= + 1 << (random_bit2 % 8); + } + // printf("Enqueue 1."); + pthread_mutex_lock(&buffer_lock); + enqueue(buffer, m); + pthread_cond_signal(&buffer_cond); + pthread_mutex_unlock(&buffer_lock); + // printf("Done!\n"); + } + } + } +} + +void *run_reverse_forwarding(void *param) +{ + msg *m; + + while (1) { + m = receive_message2(); + DIE(m == NULL, "Read error"); + + send_message1(m); + free(m); + } +} + +#define SPEED 1 +#define DELAY 2 +#define LOSS 3 +#define CORRUPT 4 +#define CORRUPT2 5 +#define REORDER 6 + +int split_param(char *p, int *type, double *value) +{ + char c[100]; + int crt = 0, t = 1; + + for (; *p != 0; p++) { + if (t && *p == '=') { + t = 0; + c[crt] = 0; + crt = 0; + + if (!strcasecmp(c, "speed")) + *type = SPEED; + else if (!strcasecmp(c, "delay")) + *type = DELAY; + else if (!strcasecmp(c, "loss")) + *type = LOSS; + else if (!strcasecmp(c, "corrupt")) + *type = CORRUPT; + else if (!strcasecmp(c, "corrupt2")) + *type = CORRUPT2; + else if (!strcasecmp(c, "reorder")) + *type = REORDER; + else { + printf("Unknown parameter %s\n", c); + return -1; + } + } else + c[crt++] = *p; + } + *value = atof(c); + return 0; +} + +int guess_hz() +{ + long long a, b, diff = 0; + int i; + + for (i = 0; i < 100; i++) { + a = now(); + // 0.1ms + usleep(100); + b = now(); + diff += (b - a); + } + + int error = (int)(diff / i - 100); + printf("Average error 100 was %d\n", error); + + diff = 0; + for (i = 0; i < 100; i++) { + a = now(); + // 0.1ms + usleep(1000); + b = now(); + diff += (b - a); + } + + error = (int)(diff / i - 1000); + printf("Average error 1000 was %d\n", error); + return error; +} + +int main(int argc, char **argv) +{ + pthread_t link_thread, fw_thread; + int i; + for (i = 1; i < argc; i++) { + int type; + double value; + if (split_param(argv[i], &type, &value) < 0) { + printf("Usage %s speed=[speed in mb/s] delay=[delay in ms] " + "loss=[percent of packets] corrupt=[percent of packets]\n", + argv[0]); + return -1; + } + + switch (type) { + case SPEED: + printf("Setting speed to %f Mb/s\n", value); + serialization_delay = 2 * 11200 / value; + break; + case DELAY: + printf("Setting delay %f to ms\n", value); + delay = value * 1000; + break; + case LOSS: + printf("Setting loss rate to %f%%\n", value); + loss = value; + break; + case CORRUPT: + printf("Setting corruption rate to %f%%\n", value); + corrupt = value; + break; + case CORRUPT2: + printf("Setting double corruption to %f%%\n", value); + corrupt2 = value; + break; + case REORDER: + printf("Setting reorder rate to %f%%\n", value); + reorder = value; + break; + } + } + +#if DEBUG + guess_hz(); +#endif + + init_sockets(); + srand(time(NULL)); + buffer = create_queue(); + assert(!pthread_create(&link_thread, NULL, link_scheduler, NULL)); + assert(!pthread_create(&fw_thread, NULL, run_forwarding, NULL)); + + run_reverse_forwarding(NULL); + return 0; +} diff --git a/lab2/link_emulator/link.h b/common/link_emulator/link.h similarity index 56% rename from lab2/link_emulator/link.h rename to common/link_emulator/link.h index 92b64db..ab2a462 100644 --- a/lab2/link_emulator/link.h +++ b/common/link_emulator/link.h @@ -1,10 +1,11 @@ -#ifndef LINK -#define LINK +#ifndef _LINK_H_ +#define _LINK_H_ + #include "lib.h" typedef struct { - msg* m; + msg *m; unsigned long long finish_time; } msg_in_flight; -#endif +#endif /* _LINK_H_ */ diff --git a/common/link_emulator/queue.c b/common/link_emulator/queue.c new file mode 100644 index 0000000..88d3196 --- /dev/null +++ b/common/link_emulator/queue.c @@ -0,0 +1,66 @@ +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include "queue.h" +#include "include/utils.h" + +void enqueue(queue * q, void *m) +{ + if (q->first == NULL) { + assert(q->last == NULL); + + q->first = (queue_entry *) malloc(sizeof(queue_entry)); + DIE(!q->first, "malloc"); + q->last = q->first; + } else { + queue_entry *t = (queue_entry *) malloc(sizeof(queue_entry)); + DIE(!t, "malloc"); + q->first->prev = t; + q->first = t; + } + + q->first->prev = NULL; + q->first->crt = m; + + q->size++; +} + +void *dequeue(queue * q) +{ + queue_entry *t; + void *m; + + if (q->first == NULL) { + assert(q->size == 0); + return NULL; + } else if (q->first == q->last) { + t = q->last; + assert(q->first->prev == NULL); + + q->first = q->last = NULL; + } else { + t = q->last; + q->last = q->last->prev; + } + + m = t->crt; + free(t); + q->size--; + + return m; +} + +queue *create_queue() +{ + queue *q = (queue *) malloc(sizeof(queue)); + DIE(!q, "malloc"); + q->first = NULL; + q->last = NULL; + q->size = 0; + return q; +} + +void destroy_queue(queue * q) +{ + assert(0); +} diff --git a/common/link_emulator/queue.h b/common/link_emulator/queue.h new file mode 100644 index 0000000..08c5a65 --- /dev/null +++ b/common/link_emulator/queue.h @@ -0,0 +1,25 @@ +#ifndef _QUEUE_H_ +#define _QUEUE_H_ + +#include "lib.h" + +struct q { + void* crt; + struct q *prev; +}; + +typedef struct q queue_entry; + +typedef struct { + int size; + queue_entry *first; + queue_entry *last; +} queue; + +void enqueue(queue *q,void *m); +void *dequeue(queue *q); + +queue *create_queue(); +void destroy_queue(queue *q); + +#endif /* _QUEUE_H_ */ diff --git a/common/run_experiment.sh b/common/run_experiment.sh new file mode 100755 index 0000000..f363f62 --- /dev/null +++ b/common/run_experiment.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +SPEED=1 +DELAY=1 +LOSS=0 +# Adjust the corruption +CORRUPT=0 + +# Second bit corruption rate +CORRUPT2=0 + +{ + pkill -9 link + pkill -9 recv + pkill -9 send +} &> /dev/null + +./link_emulator/link speed=$SPEED delay=$DELAY loss=$LOSS corrupt=$CORRUPT \ + corrupt2=$CORRUPT2 > link_emulator.out 2> link_emulator.err & +sleep 1 +./recv & +sleep 1 + +./send diff --git a/common/utils.c b/common/utils.c new file mode 100644 index 0000000..7714e53 --- /dev/null +++ b/common/utils.c @@ -0,0 +1,42 @@ +#include "include/utils.h" + +#include <stdio.h> +#include <stdlib.h> + +#define HEX_LINESIZE 16 + +void hex_dump(const void * addr, size_t size) +{ + int i; + unsigned char buff[HEX_LINESIZE+1]; + const unsigned char * pc = (const unsigned char *)addr; + + // Process every byte in the data. + for (i = 0; i < size; i++) { + // Multiple of HEX_LINESIZE means new or first line (with line offset). + if ((i % HEX_LINESIZE) == 0) { + // Only print previous-line ASCII buffer for lines beyond first. + if (i != 0) printf(" %s\n", buff); + printf(" %04x ", i); + } + + // Now the hex code for the specific character. + printf(" %02x", pc[i]); + + // And buffer a printable ASCII character for later. + if ((pc[i] < 0x20) || (pc[i] > 0x7e)) // isprint() may be better. + buff[i % HEX_LINESIZE] = '.'; + else + buff[i % HEX_LINESIZE] = pc[i]; + buff[(i % HEX_LINESIZE) + 1] = '\0'; + } + + // Pad out last line if not exactly HEX_LINESIZE characters. + while ((i % HEX_LINESIZE) != 0) { + printf(" "); + i++; + } + + // And print the final ASCII buffer. + printf(" %s\n", buff); +} diff --git a/lab2/Makefile b/lab2/Makefile index 7715dbc..20341b2 100644 --- a/lab2/Makefile +++ b/lab2/Makefile @@ -1,19 +1,19 @@ -CFLAGS= -Wall -Werror -Wno-error=unused-variable +CFLAGS= -Wall -Werror -Wno-error=unused-variable -I../common/ all: send recv +../common/utils.o: + $(MAKE) -C ../common + link_emulator/lib.o: $(MAKE) -C link_emulator -send: send.o link_emulator/lib.o - gcc $(CFLAGS) -g send.o link_emulator/lib.o -o send - -recv: recv.o link_emulator/lib.o - gcc $(CFLAGS) -g recv.o link_emulator/lib.o -o recv +send: send.o link_emulator/lib.o ../common/utils.o -.c.o: - gcc $(CFLAGS) -g -c $? +recv: recv.o link_emulator/lib.o ../common/utils.o clean: $(MAKE) -C link_emulator clean -rm -f *.o send recv + +.PHONY: all clean diff --git a/lab2/common.h b/lab2/common.h index 18344a6..94b55bd 100644 --- a/lab2/common.h +++ b/lab2/common.h @@ -5,14 +5,9 @@ /* Atributul este folosit pentru a anunta compilatorul sa nu alinieze structura */ /* DELIM | DATE | DELIM */ struct __attribute__((packed)) Frame { - char frame_delim_start[2]; /* DEL STX */ + char frame_delim_start[2]; /* DLE STX */ + /* TODO 2: Add source and destination */ char payload[30]; /* Datele pe care vrem sa le transmitem */ - char frame_delim_end[2]; /* DEL ETX */ + char frame_delim_end[2]; /* DLE ETX */ }; - -/* Sends one character to the other end via the Physical layer */ -int send_byte(char c); -/* Receives one character from the other end, if nothing is sent by the other end, returns a random character */ -char recv_byte(); - diff --git a/lab2/link_emulator b/lab2/link_emulator new file mode 120000 index 0000000..ce372f4 --- /dev/null +++ b/lab2/link_emulator @@ -0,0 +1 @@ +../common/link_emulator \ No newline at end of file diff --git a/lab2/link_emulator.err b/lab2/link_emulator.err new file mode 100644 index 0000000..e69de29 diff --git a/lab2/link_emulator.out b/lab2/link_emulator.out new file mode 100644 index 0000000..e69de29 diff --git a/lab2/link_emulator/Makefile b/lab2/link_emulator/Makefile deleted file mode 100644 index b2105de..0000000 --- a/lab2/link_emulator/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -all: link lib.o - -link: link.o queue.o - gcc -g link.o queue.o -o link -lpthread - -.c.o: - gcc -Wall -g -c $? -lpthread - -clean: - -rm *.o link diff --git a/lab2/link_emulator/lib.c b/lab2/link_emulator/lib.c deleted file mode 100644 index 1d9e87b..0000000 --- a/lab2/link_emulator/lib.c +++ /dev/null @@ -1,105 +0,0 @@ -#include "lib.h" -#include <arpa/inet.h> -#include <poll.h> -//#include <stropts.h> -#include <netinet/in.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <unistd.h> -#include <string.h> - -struct sockaddr_in addr_local, addr_remote; -int s; -struct pollfd fds[1]; - -void set_local_port(int port) -{ - memset((char *) &addr_local, 0, sizeof(addr_local)); - addr_local.sin_family = AF_INET; - addr_local.sin_port = htons(port); - addr_local.sin_addr.s_addr = htonl(INADDR_ANY); -} - -void set_remote(char* ip, int port){ - memset((char *) &addr_remote, 0, sizeof(addr_remote)); - addr_remote.sin_family = AF_INET; - addr_remote.sin_port = htons(port); - if (inet_aton(ip, &addr_remote.sin_addr)==0) { - perror("inet_aton failed\n"); - exit(1); - } -} - -void init(char* remote, int REMOTE_PORT){ - if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1){ - perror("Error creating socket"); - exit(1); - } - - set_local_port(0); - set_remote(remote,REMOTE_PORT); - - if (bind(s, (struct sockaddr*)&addr_local, sizeof(addr_local))==-1){ - perror("Failed to bind"); - exit(1); - } - - fds[0].fd = s; - fds[0].events = POLLIN; - - msg m; - send_message(&m); -} - -int send_message(const msg* m){ - return sendto(s, m, sizeof(msg), 0,(struct sockaddr*) &addr_remote, sizeof(addr_remote)); -} - -/*msg* receive_message(){ - msg* ret = (msg*)malloc(sizeof(msg)); - if (recvfrom(s, ret, sizeof(msg), 0, NULL, NULL)==-1){ - free(ret); - return NULL; - } - return ret; - }*/ - -int recv_message(msg* ret){ - return recvfrom(s, ret, sizeof(msg), 0, NULL, NULL); -} - -int send_byte(char c) { - msg m; - m.len = 1; - m.payload[0] = c; - printf("Sending byte %c \n", m.payload[0]); - return send_message(&m); -} - -char recv_byte() { - msg m; - int ret; - usleep(100000); - ret = recvfrom(s, &m, sizeof(msg), MSG_DONTWAIT, NULL, NULL); - if (ret < 0) { - char c = rand() % 128; - return c; - - } else { - return m.payload[0]; - } -} - -//timeout in millis -/*msg* receive_message_timeout(int timeout){ - int ret = poll(fds,1,timeout); - - if (ret>0){ - if (fds[0].revents & POLLIN) - return receive_message(); - } - - return NULL; - }*/ diff --git a/lab2/link_emulator/lib.h b/lab2/link_emulator/lib.h deleted file mode 100644 index b6f98b0..0000000 --- a/lab2/link_emulator/lib.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef LIB -#define LIB - -#define MAX_LEN 1400 - -typedef struct { - // int type; - int len; - char payload[MAX_LEN]; -} msg; - -void init(char* remote,int remote_port); -void set_local_port(int port); -void set_remote(char* ip, int port); -int send_message(const msg* m); -int recv_message(msg* r); -int send_byte(char c); -char recv_byte(); - -//msg* receive_message_timeout(int timeout); - -#endif - diff --git a/lab2/link_emulator/link.c b/lab2/link_emulator/link.c deleted file mode 100644 index a6c1c73..0000000 --- a/lab2/link_emulator/link.c +++ /dev/null @@ -1,415 +0,0 @@ -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <sys/time.h> -#include <arpa/inet.h> -#include <netinet/in.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <unistd.h> -#include <string.h> -//#include <asm/param.h> -#include "queue.h" -#include "link.h" - -#define DEBUG 0 - -int BUFFER_SIZE=1000; - -int serialization_delay = 1000; -int delay = 1000; -int loss = 0; -int corrupt = 0; - -#define CHANNEL_BUSY 1 -#define CHANNEL_IDLE 0 - -#define LOCAL_PORT1 10000 -#define LOCAL_PORT2 10001 - -pthread_mutex_t buffer_lock = PTHREAD_MUTEX_INITIALIZER; -pthread_cond_t buffer_cond = PTHREAD_COND_INITIALIZER; -queue* buffer; - -struct sockaddr_in local_addr1, remote_addr1; -struct sockaddr_in local_addr2, remote_addr2; - -int s1,s2; -socklen_t sz; - -//1 if a message was received on this link -int link_up1 = 0; -int link_up2 = 0; - -void init_sockets() -{ - /*LOCAL ADDRESSES*/ - - memset((char *) &local_addr1, 0, sizeof(local_addr1)); - local_addr1.sin_family = AF_INET; - local_addr1.sin_port = htons(LOCAL_PORT1); - local_addr1.sin_addr.s_addr = htonl(INADDR_ANY); - - memset((char *) &local_addr2, 0, sizeof(local_addr2)); - local_addr2.sin_family = AF_INET; - local_addr2.sin_port = htons(LOCAL_PORT2); - local_addr2.sin_addr.s_addr = htonl(INADDR_ANY); - - if ((s1=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1){ - perror("Error creating socket"); - exit(1); - } - - //now bind - if (bind(s1, (struct sockaddr*)&local_addr1, sizeof(local_addr1))==-1){ - perror("Failed to bind s1"); - exit(1); - } - - if ((s2=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1){ - perror("Error creating socket 2"); - exit(1); - } - - if (bind(s2, (struct sockaddr*)&local_addr2, sizeof(local_addr2))==-1){ - perror("Failed to bind s2"); - exit(1); - } -} - -int send_message1(const msg* m){ - if (!link_up1){ - printf("Trying to send a message but remote peer is not connected on my port %d\n",LOCAL_PORT1); - } - return sendto(s1, m, sizeof(msg), 0,(struct sockaddr*) &remote_addr1, sizeof(remote_addr1)); -} - -msg* receive_message1(){ - msg* ret; - - a: - ret = (msg*)malloc(sizeof(msg)); - - if (!link_up1){ - sz = sizeof(remote_addr1); - if (recvfrom(s1, ret, sizeof(msg), 0, (struct sockaddr*)&remote_addr1, &sz)==-1){ - free(ret); - return NULL; - } - - link_up1 = 1; - -#if DEBUG - printf("Link 1 is up, remote addr is %s port %d\n",inet_ntoa(remote_addr1.sin_addr),ntohs(remote_addr1.sin_port)); -#endif - - free(ret); - goto a; - } - else if (recvfrom(s1, ret, sizeof(msg), 0, NULL,NULL)==-1){ - free(ret); - return NULL; - } - return ret; -} - -int send_message2(const msg* m){ - if (!link_up2){ - printf("Trying to send a message but remote peer is not connected on my port %d\n",LOCAL_PORT2); - } - return sendto(s2, m, sizeof(msg), 0,(struct sockaddr*) &remote_addr2, sizeof(remote_addr2)); -} - -msg* receive_message2(){ - msg* ret; - - a: - ret = (msg*)malloc(sizeof(msg)); - if (!link_up2){ - sz = sizeof(remote_addr2); - if (recvfrom(s2, ret, sizeof(msg), 0, (struct sockaddr*)&remote_addr2, &sz)==-1){ - free(ret); - return NULL; - } - link_up2 = 1; - -#if DEBUG - printf("Link 2 is up, remote addr is %s port %d\n",inet_ntoa(remote_addr2.sin_addr),ntohs(remote_addr2.sin_port)); -#endif - - free(ret); - goto a; - } - else - if (recvfrom(s2, ret, sizeof(msg), 0, NULL, NULL)==-1){ - free(ret); - return NULL; - } - - return ret; -} - -unsigned long long now(){ - struct timeval b; - gettimeofday(&b,NULL); - return (unsigned long long)b.tv_sec*1000000+b.tv_usec; -} - -void* link_scheduler(void *argument) -{ - msg_in_flight* mif; - queue* in_flight = create_queue(); - long long idle_time = 0; - long long crt_time,wait_time_idle,wait_time_send; - int stuff; - - while (1){ - crt_time = now(); - -#if DEBUG - printf("In flight size %d at %lld\n",in_flight->size, crt_time); -#endif - - while (in_flight->size>0){ - msg_in_flight* last = (msg_in_flight*)in_flight->last->crt; - if (crt_time<last->finish_time){ - break; - } - - //else send first packet on the wire - mif = (msg_in_flight*)dequeue(in_flight); - if (!mif){ - printf("Error in deque: expecting non null msg!\n"); - exit(1); - } - if (send_message2(mif->m)<=0) - perror("SNDMSG2"); - -#if DEBUG - printf("Sending message\n"); -#endif - - free(mif->m); - free(mif); - mif = NULL; - } - - pthread_mutex_lock( &buffer_lock ); - stuff = buffer->size>0; - pthread_mutex_unlock( &buffer_lock ); - -#if DEBUG - printf("Stuff is %d\n",stuff); -#endif - - wait_time_send = wait_time_idle = 0; - - //crt_time = now(); - - //now see if we can put stuff in flight - if (stuff && crt_time>=idle_time){ - idle_time = crt_time + serialization_delay; - - mif = (msg_in_flight*)malloc(sizeof(msg_in_flight)); - assert(mif); - - pthread_mutex_lock( &buffer_lock ); - mif->m = (msg*)dequeue(buffer); - pthread_mutex_unlock( &buffer_lock ); - - assert(mif->m); - mif->finish_time = crt_time + serialization_delay + delay; - - //send message here from buffer to link - enqueue(in_flight,mif); - -#if DEBUG - printf("Enquing message\n"); -#endif - } - wait_time_idle = idle_time - crt_time; - - if (in_flight->size>0){ - msg_in_flight* last = (msg_in_flight*)in_flight->last->crt; - wait_time_send = last->finish_time-crt_time; - } - - if (wait_time_idle>0 || wait_time_send>0){ - long long wait_time = 0; - if (wait_time_idle>0) wait_time = wait_time_idle; - if (wait_time_send>0&&wait_time_send<wait_time) - wait_time = wait_time_send; - - //printf("Sleeping %lld\n", wait_time); - usleep(wait_time); - } - else { - pthread_mutex_lock( &buffer_lock ); - assert(!buffer->size); -#if DEBUG - printf("Waiting on cond\n"); -#endif - pthread_cond_wait(&buffer_cond,&buffer_lock); - pthread_mutex_unlock( &buffer_lock ); - } - } - - return NULL; -} - -void* run_forwarding(void* param){ - msg *m; - - while (1){ - int overflow; - m = receive_message1(); - if (m==NULL){ - perror("Read error"); - exit(1); - } - - //check queue space - pthread_mutex_lock( &buffer_lock ); - overflow = buffer->size>=BUFFER_SIZE; - pthread_mutex_unlock( &buffer_lock ); - - if (overflow || (rand()%100)<loss) { - //just drop message - free(m); - printf("Dropped packet\n"); - } - else { - if (rand()%100 < corrupt){ - m->payload[rand()%m->len] = rand()%128; - } - //printf("Enqueue 1."); - pthread_mutex_lock( &buffer_lock ); - enqueue(buffer,m); - pthread_cond_signal(&buffer_cond); - pthread_mutex_unlock(&buffer_lock); - //printf("Done!\n"); - } - } -} - -void* run_reverse_forwarding(void* param){ - msg *m; - - while (1){ - m = receive_message2(); - if (m==NULL){ - perror("Read error"); - exit(1); - } - - send_message1(m); - free(m); - } -} - -#define SPEED 1 -#define DELAY 2 -#define LOSS 3 -#define CORRUPT 4 - -int split_param(char* p,int * type, double* value){ - char c[100]; - int crt = 0, t=1; - - for (;*p!=0;p++){ - if (t && *p=='='){ - t = 0; - c[crt] = 0; - crt = 0; - - if (!strcasecmp(c,"speed")) - *type = SPEED; - else if (!strcasecmp(c,"delay")) - *type = DELAY; - else if (!strcasecmp(c,"loss")) - *type = LOSS; - else if (!strcasecmp(c,"corrupt")) - *type = CORRUPT; - else { - printf ("Unknown parameter %s\n",c); - return -1; - } - } - else c[crt++] = *p; - } - *value = atof(c); - return 0; -} - -int guess_hz(){ - long long a,b,diff = 0; - int i; - - for (i=0;i<100;i++){ - a = now(); - //0.1ms - usleep(100); - b = now(); - diff += (b-a); - } - - int error = (int)(diff/i-100); - printf("Average error 100 was %d\n",error); - - diff = 0; - for (i=0;i<100;i++){ - a = now(); - //0.1ms - usleep(1000); - b = now(); - diff += (b-a); - } - - error = (int)(diff/i-1000); - printf("Average error 1000 was %d\n",error); - return error; -} - -int main(int argc, char** argv){ - pthread_t link_thread, fw_thread; - int i; - for (i=1;i<argc;i++){ - int type; - double value; - if (split_param(argv[i],&type,&value)<0){ - printf("Usage %s speed=[speed in mb/s] delay=[delay in ms] loss=[percent of packets] corrupt=[percent of packets]\n",argv[0]); - return -1; - } - - switch(type){ - case SPEED: - printf("Setting speed to %f Mb/s\n",value); - serialization_delay = 2*11200/value;break; - case DELAY: - printf("Setting delay %f to ms\n",value); - delay = value*1000; break; - case LOSS: - printf("Setting loss rate to %f%%\n",value); - loss = value; break; - case CORRUPT: - printf("Setting corruption rate to %f%%\n",value); - corrupt = value; break; - } - } - -#if DEBUG - guess_hz(); -#endif - - init_sockets(); - srand(time(NULL)); - buffer = create_queue(); - assert(!pthread_create(&link_thread, NULL, link_scheduler, NULL)); - assert(!pthread_create(&fw_thread, NULL, run_forwarding, NULL)); - - run_reverse_forwarding(NULL); - return 0; -} diff --git a/lab2/link_emulator/queue.c b/lab2/link_emulator/queue.c deleted file mode 100644 index daced7e..0000000 --- a/lab2/link_emulator/queue.c +++ /dev/null @@ -1,61 +0,0 @@ -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include "queue.h" - -void enqueue(queue* q,void* m){ - if (q->first==NULL){ - assert(q->last==NULL); - - q->first = (queue_entry*)malloc(sizeof(queue_entry)); - q->last = q->first; - } - else { - queue_entry * t = (queue_entry*)malloc(sizeof(queue_entry)); - q->first->prev = t; - q->first = t; - } - - q->first->prev = NULL; - q->first->crt = m; - - q->size++; -} - -void* dequeue(queue* q){ - queue_entry * t; - void* m; - - if (q->first==NULL){ - assert(q->size==0); - return NULL; - } - else if (q->first==q->last){ - t = q->last; - assert(q->first->prev==NULL); - - q->first = q->last = NULL; - } - else { - t = q->last; - q->last = q->last->prev; - } - - m = t->crt; - free(t); - q->size--; - - return m; -} - -queue* create_queue(){ - queue* q = (queue*)malloc(sizeof(queue)); - q->first = NULL; - q->last = NULL; - q->size = 0; - return q; -} - -void destroy_queue(queue* q){ - assert(0); -} diff --git a/lab2/link_emulator/queue.h b/lab2/link_emulator/queue.h deleted file mode 100644 index 9b6a45b..0000000 --- a/lab2/link_emulator/queue.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef QUEUE -#define QUEUE -#include "lib.h" - - -struct q { - void* crt; - struct q* prev; -}; - -typedef struct q queue_entry; - -typedef struct { - int size; - queue_entry* first; - queue_entry* last; -} queue; - -void enqueue(queue* q,void* m); -void* dequeue(queue* q); - -queue* create_queue(); -void destroy_queue(queue* q); - -#endif diff --git a/lab2/recv b/lab2/recv new file mode 100755 index 0000000000000000000000000000000000000000..ec239882d193b863ef0f6be1622bfcd711d80f54 GIT binary patch literal 23120 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 M3W>HHg&dUq5A*^SzW@LL literal 0 HcmV?d00001 diff --git a/lab2/recv.c b/lab2/recv.c index 99dba5d..3e6d72d 100644 --- a/lab2/recv.c +++ b/lab2/recv.c @@ -4,14 +4,20 @@ #include <unistd.h> #include <fcntl.h> #include "link_emulator/lib.h" - -/* Do not touch these two */ +#include "include/utils.h" + +/** + * You can change these to communicate with another colleague. + * There are several factors that could stop this from working over the + * internet, but if you're on the same network it should work. + * Just fill in their IP here and make sure that you use the same port. + */ #define HOST "127.0.0.1" #define PORT 10001 #include "common.h" -/* Our unqiue layer 2 ID */ +/* Our unique layer 2 ID */ static int ID = 123131; /* Function which our protocol implementation will provide to the upper layer. */ @@ -32,10 +38,11 @@ int recv_frame(char *buf, int size) } int main(int argc,char** argv){ - /* Do not touch this */ + /* Don't modify this */ init(HOST,PORT); - + // TODO remove these recives, whih are hardcoded to receive a "Hello" + // message, and replace them with code that can receive any message. char c; /* Wait for the start of a frame */ diff --git a/lab2/run_experiment.sh b/lab2/run_experiment.sh deleted file mode 100755 index fadeeb3..0000000 --- a/lab2/run_experiment.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -SPEED=1 -DELAY=1 -LOSS=0 -CORRUPT=0 - -{ - killall link - killall recv - killall send -} &> /dev/null - -./link_emulator/link speed=$SPEED delay=$DELAY loss=$LOSS corrupt=$CORRUPT &> /dev/null & -sleep 1 -./recv & -sleep 1 - -./send - -#sleep 2 -#echo "Finished transfer, checking files" -#diff tema.txt recv_tema.txt diff --git a/lab2/run_experiment.sh b/lab2/run_experiment.sh new file mode 120000 index 0000000..a204cff --- /dev/null +++ b/lab2/run_experiment.sh @@ -0,0 +1 @@ +../common/run_experiment.sh \ No newline at end of file diff --git a/lab2/send b/lab2/send new file mode 100755 index 0000000000000000000000000000000000000000..4599f0679206ff30a524decc8981d7142fcac658 GIT binary patch literal 23072 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 literal 0 HcmV?d00001 diff --git a/lab2/send.c b/lab2/send.c index 33fdd73..7e70a31 100644 --- a/lab2/send.c +++ b/lab2/send.c @@ -6,8 +6,14 @@ #include <sys/types.h> #include <sys/stat.h> #include "link_emulator/lib.h" - -/* We don't touch this */ +#include "include/utils.h" + +/** + * You can change these to communicate with another colleague. + * There are several factors that could stop this from working over the + * internet, but if you're on the same network it should work. + * Just fill in their IP here and make sure that you use the same port. + */ #define HOST "127.0.0.1" #define PORT 10000 @@ -38,6 +44,8 @@ int main(int argc,char** argv){ // Don't touch this init(HOST,PORT); + // TODO remove these sends, whih are hardcoded to send a "Hello" + // message, and replace them with code that can send any message. /* Send Hello */ send_byte(DLE); send_byte(STX); diff --git a/lab3/Makefile b/lab3/Makefile index 3640948..c1f3d41 100644 --- a/lab3/Makefile +++ b/lab3/Makefile @@ -1,21 +1,21 @@ -CFLAGS= -Wall -Werror -Wno-error=unused-variable +CFLAGS= -Wall -Werror -Wno-error=unused-variable -I../common/ all: send recv +../common/utils.o: + $(MAKE) -C ../common + link_emulator/lib.o: $(MAKE) -C link_emulator -send: send.o link_emulator/lib.o common.o - gcc $(CFLAGS) -g send.o link_emulator/lib.o common.o -o send +send: send.o link_emulator/lib.o common.o ../common/utils.o -recv: recv.o link_emulator/lib.o common.o - gcc $(CFLAGS) -g recv.o link_emulator/lib.o common.o -o recv +recv: recv.o link_emulator/lib.o common.o ../common/utils.o common.o: common.c common.h -.c.o: - gcc $(CFLAGS) -g -c $? - clean: $(MAKE) -C link_emulator clean -rm -f *.o send recv common.h.gch + +.PHONY: all clean diff --git a/lab3/link_emulator b/lab3/link_emulator new file mode 120000 index 0000000..ce372f4 --- /dev/null +++ b/lab3/link_emulator @@ -0,0 +1 @@ +../common/link_emulator \ No newline at end of file diff --git a/lab3/link_emulator/lib.c b/lab3/link_emulator/lib.c deleted file mode 100644 index 360ffbe..0000000 --- a/lab3/link_emulator/lib.c +++ /dev/null @@ -1,103 +0,0 @@ -#include "lib.h" -#include <arpa/inet.h> -#include <poll.h> -//#include <stropts.h> -#include <netinet/in.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <unistd.h> -#include <string.h> - -struct sockaddr_in addr_local, addr_remote; -int s; -struct pollfd fds[1]; - -static int send_message(const msg* m); - -void set_local_port(int port) -{ - memset((char *) &addr_local, 0, sizeof(addr_local)); - addr_local.sin_family = AF_INET; - addr_local.sin_port = htons(port); - addr_local.sin_addr.s_addr = htonl(INADDR_ANY); -} - -void set_remote(char* ip, int port){ - memset((char *) &addr_remote, 0, sizeof(addr_remote)); - addr_remote.sin_family = AF_INET; - addr_remote.sin_port = htons(port); - if (inet_aton(ip, &addr_remote.sin_addr)==0) { - perror("inet_aton failed\n"); - exit(1); - } -} - -void init(char* remote, int REMOTE_PORT){ - if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1){ - perror("Error creating socket"); - exit(1); - } - - set_local_port(0); - set_remote(remote,REMOTE_PORT); - - if (bind(s, (struct sockaddr*)&addr_local, sizeof(addr_local))==-1){ - perror("Failed to bind"); - exit(1); - } - - fds[0].fd = s; - fds[0].events = POLLIN; - - msg m; - send_message(&m); -} - -int send_message(const msg* m){ - return sendto(s, m, sizeof(msg), 0,(struct sockaddr*) &addr_remote, sizeof(addr_remote)); -} - -void link_send(void *buf, int len) { - msg m; - - memcpy(m.payload, buf, len); - m.len = len; - - send_message(&m); -} - -/*msg* receive_message(){ - msg* ret = (msg*)malloc(sizeof(msg)); - if (recvfrom(s, ret, sizeof(msg), 0, NULL, NULL)==-1){ - free(ret); - return NULL; - } - return ret; - }*/ - -int recv_message(msg* ret){ - return recvfrom(s, ret, sizeof(msg), 0, NULL, NULL); -} - - -int link_recv(void *buf, int len) { - msg m; - recv_message(&m); - int r = m.len < len ? m.len : len; - memcpy(buf, m.payload, r); - return r; -} - -//timeout in millis -/*msg* receive_message_timeout(int timeout){ - int ret = poll(fds,1,timeout); - - if (ret>0){ - if (fds[0].revents & POLLIN) - return receive_message(); - } - - return NULL; - }*/ diff --git a/lab3/link_emulator/lib.h b/lab3/link_emulator/lib.h deleted file mode 100644 index 5d8634c..0000000 --- a/lab3/link_emulator/lib.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef LIB -#define LIB - -#include <stddef.h> - -#define MAX_LEN 1500 - -typedef struct { - int len; - char payload[MAX_LEN]; -} msg; - -void init(char* remote,int remote_port); -void set_local_port(int port); -void set_remote(char* ip, int port); -int link_recv(void *buf, int len); -void link_send(void *buf, int len); - -#endif diff --git a/lab3/link_emulator/link.c b/lab3/link_emulator/link.c deleted file mode 100644 index 71b18ab..0000000 --- a/lab3/link_emulator/link.c +++ /dev/null @@ -1,428 +0,0 @@ -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <sys/time.h> -#include <arpa/inet.h> -#include <netinet/in.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <unistd.h> -#include <string.h> -//#include <asm/param.h> -#include "queue.h" -#include "link.h" - -#define DEBUG 0 - -int BUFFER_SIZE=1000; - -int serialization_delay = 1000; -int delay = 1000; -int loss = 0; -int corrupt = 0; -int corrupt2 = 0; - -#define CHANNEL_BUSY 1 -#define CHANNEL_IDLE 0 - -#define LOCAL_PORT1 10000 -#define LOCAL_PORT2 10001 - -pthread_mutex_t buffer_lock = PTHREAD_MUTEX_INITIALIZER; -pthread_cond_t buffer_cond = PTHREAD_COND_INITIALIZER; -queue* buffer; - -struct sockaddr_in local_addr1, remote_addr1; -struct sockaddr_in local_addr2, remote_addr2; - -int s1,s2; -socklen_t sz; - -//1 if a message was received on this link -int link_up1 = 0; -int link_up2 = 0; - -void init_sockets() -{ - /*LOCAL ADDRESSES*/ - - memset((char *) &local_addr1, 0, sizeof(local_addr1)); - local_addr1.sin_family = AF_INET; - local_addr1.sin_port = htons(LOCAL_PORT1); - local_addr1.sin_addr.s_addr = htonl(INADDR_ANY); - - memset((char *) &local_addr2, 0, sizeof(local_addr2)); - local_addr2.sin_family = AF_INET; - local_addr2.sin_port = htons(LOCAL_PORT2); - local_addr2.sin_addr.s_addr = htonl(INADDR_ANY); - - if ((s1=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1){ - perror("Error creating socket"); - exit(1); - } - - //now bind - if (bind(s1, (struct sockaddr*)&local_addr1, sizeof(local_addr1))==-1){ - perror("Failed to bind s1"); - exit(1); - } - - if ((s2=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1){ - perror("Error creating socket 2"); - exit(1); - } - - if (bind(s2, (struct sockaddr*)&local_addr2, sizeof(local_addr2))==-1){ - perror("Failed to bind s2"); - exit(1); - } -} - -int send_message1(const msg* m){ - if (!link_up1){ - printf("Trying to send a message but remote peer is not connected on my port %d\n",LOCAL_PORT1); - } - return sendto(s1, m, sizeof(msg), 0,(struct sockaddr*) &remote_addr1, sizeof(remote_addr1)); -} - -msg* receive_message1(){ - msg* ret; - - a: - ret = (msg*)malloc(sizeof(msg)); - - if (!link_up1){ - sz = sizeof(remote_addr1); - if (recvfrom(s1, ret, sizeof(msg), 0, (struct sockaddr*)&remote_addr1, &sz)==-1){ - free(ret); - return NULL; - } - - link_up1 = 1; - -#if DEBUG - printf("Link 1 is up, remote addr is %s port %d\n",inet_ntoa(remote_addr1.sin_addr),ntohs(remote_addr1.sin_port)); -#endif - - free(ret); - goto a; - } - else if (recvfrom(s1, ret, sizeof(msg), 0, NULL,NULL)==-1){ - free(ret); - return NULL; - } - return ret; -} - -int send_message2(const msg* m){ - if (!link_up2){ - printf("Trying to send a message but remote peer is not connected on my port %d\n",LOCAL_PORT2); - } - return sendto(s2, m, sizeof(msg), 0,(struct sockaddr*) &remote_addr2, sizeof(remote_addr2)); -} - -msg* receive_message2(){ - msg* ret; - - a: - ret = (msg*)malloc(sizeof(msg)); - if (!link_up2){ - sz = sizeof(remote_addr2); - if (recvfrom(s2, ret, sizeof(msg), 0, (struct sockaddr*)&remote_addr2, &sz)==-1){ - free(ret); - return NULL; - } - link_up2 = 1; - -#if DEBUG - printf("Link 2 is up, remote addr is %s port %d\n",inet_ntoa(remote_addr2.sin_addr),ntohs(remote_addr2.sin_port)); -#endif - - free(ret); - goto a; - } - else - if (recvfrom(s2, ret, sizeof(msg), 0, NULL, NULL)==-1){ - free(ret); - return NULL; - } - - return ret; -} - -unsigned long long now(){ - struct timeval b; - gettimeofday(&b,NULL); - return (unsigned long long)b.tv_sec*1000000+b.tv_usec; -} - -void* link_scheduler(void *argument) -{ - msg_in_flight* mif; - queue* in_flight = create_queue(); - long long idle_time = 0; - long long crt_time,wait_time_idle,wait_time_send; - int stuff; - - while (1){ - crt_time = now(); - -#if DEBUG - printf("In flight size %d at %lld\n",in_flight->size, crt_time); -#endif - - while (in_flight->size>0){ - msg_in_flight* last = (msg_in_flight*)in_flight->last->crt; - if (crt_time<last->finish_time){ - break; - } - - //else send first packet on the wire - mif = (msg_in_flight*)dequeue(in_flight); - if (!mif){ - printf("Error in deque: expecting non null msg!\n"); - exit(1); - } - if (send_message2(mif->m)<=0) - perror("SNDMSG2"); - -#if DEBUG - printf("Sending message\n"); -#endif - - free(mif->m); - free(mif); - mif = NULL; - } - - pthread_mutex_lock( &buffer_lock ); - stuff = buffer->size>0; - pthread_mutex_unlock( &buffer_lock ); - -#if DEBUG - printf("Stuff is %d\n",stuff); -#endif - - wait_time_send = wait_time_idle = 0; - - //crt_time = now(); - - //now see if we can put stuff in flight - if (stuff && crt_time>=idle_time){ - idle_time = crt_time + serialization_delay; - - mif = (msg_in_flight*)malloc(sizeof(msg_in_flight)); - assert(mif); - - pthread_mutex_lock( &buffer_lock ); - mif->m = (msg*)dequeue(buffer); - pthread_mutex_unlock( &buffer_lock ); - - assert(mif->m); - mif->finish_time = crt_time + serialization_delay + delay; - - //send message here from buffer to link - enqueue(in_flight,mif); - -#if DEBUG - printf("Enquing message\n"); -#endif - } - wait_time_idle = idle_time - crt_time; - - if (in_flight->size>0){ - msg_in_flight* last = (msg_in_flight*)in_flight->last->crt; - wait_time_send = last->finish_time-crt_time; - } - - if (wait_time_idle>0 || wait_time_send>0){ - long long wait_time = 0; - if (wait_time_idle>0) wait_time = wait_time_idle; - if (wait_time_send>0&&wait_time_send<wait_time) - wait_time = wait_time_send; - - //printf("Sleeping %lld\n", wait_time); - usleep(wait_time); - } - else { - pthread_mutex_lock( &buffer_lock ); - assert(!buffer->size); -#if DEBUG - printf("Waiting on cond\n"); -#endif - pthread_cond_wait(&buffer_cond,&buffer_lock); - pthread_mutex_unlock( &buffer_lock ); - } - } - - return NULL; -} - -void* run_forwarding(void* param){ - msg *m; - - while (1){ - int overflow; - m = receive_message1(); - if (m==NULL){ - perror("Read error"); - exit(1); - } - - //check queue space - pthread_mutex_lock( &buffer_lock ); - overflow = buffer->size>=BUFFER_SIZE; - pthread_mutex_unlock( &buffer_lock ); - - if (overflow || (rand()%100)<loss) { - //just drop message - free(m); - printf("Dropped packet\n"); - } - else { - if (rand()%100 < corrupt){ - //flip a random bit in a randomly chosen byte of the payload - int random_byte = rand() % m->len; - int random_bit = rand(); - m->payload[random_byte] ^= 1 << (random_bit % 8); - if (corrupt2) - m->payload[random_byte] ^= 1 << (random_bit % 8); - } - //printf("Enqueue 1."); - pthread_mutex_lock( &buffer_lock ); - enqueue(buffer,m); - pthread_cond_signal(&buffer_cond); - pthread_mutex_unlock(&buffer_lock); - //printf("Done!\n"); - } - } -} - -void* run_reverse_forwarding(void* param){ - msg *m; - - while (1){ - m = receive_message2(); - if (m==NULL){ - perror("Read error"); - exit(1); - } - - send_message1(m); - free(m); - } -} - -#define SPEED 1 -#define DELAY 2 -#define LOSS 3 -#define CORRUPT 4 -#define CORRUPT2 5 - -int split_param(char* p,int * type, double* value){ - char c[100]; - int crt = 0, t=1; - - for (;*p!=0;p++){ - if (t && *p=='='){ - t = 0; - c[crt] = 0; - crt = 0; - - if (!strcasecmp(c,"speed")) - *type = SPEED; - else if (!strcasecmp(c,"delay")) - *type = DELAY; - else if (!strcasecmp(c,"loss")) - *type = LOSS; - else if (!strcasecmp(c,"corrupt")) - *type = CORRUPT; - else if (!strcasecmp(c,"corrupt2")) - *type = CORRUPT2; - else { - printf ("Unknown parameter %s\n",c); - return -1; - } - } - else c[crt++] = *p; - } - *value = atof(c); - return 0; -} - -int guess_hz(){ - long long a,b,diff = 0; - int i; - - for (i=0;i<100;i++){ - a = now(); - //0.1ms - usleep(100); - b = now(); - diff += (b-a); - } - - int error = (int)(diff/i-100); - printf("Average error 100 was %d\n",error); - - diff = 0; - for (i=0;i<100;i++){ - a = now(); - //0.1ms - usleep(1000); - b = now(); - diff += (b-a); - } - - error = (int)(diff/i-1000); - printf("Average error 1000 was %d\n",error); - return error; -} - -int main(int argc, char** argv){ - pthread_t link_thread, fw_thread; - int i; - for (i=1;i<argc;i++){ - int type; - double value; - if (split_param(argv[i],&type,&value)<0){ - printf("Usage %s speed=[speed in mb/s] delay=[delay in ms] loss=[percent of packets] corrupt=[percent of packets]\n",argv[0]); - return -1; - } - - switch(type){ - case SPEED: - printf("Setting speed to %f Mb/s\n",value); - serialization_delay = 2*11200/value;break; - case DELAY: - printf("Setting delay %f to ms\n",value); - delay = value*1000; break; - case LOSS: - printf("Setting loss rate to %f%%\n",value); - loss = value; break; - case CORRUPT: - printf("Setting corruption rate to %f%%\n",value); - corrupt = value; break; - - case CORRUPT2: - printf("Setting double corruption to %f\n", value); - corrupt2 = value; break; - } - } - -#if DEBUG - guess_hz(); -#endif - - init_sockets(); - srand(time(NULL)); - buffer = create_queue(); - assert(!pthread_create(&link_thread, NULL, link_scheduler, NULL)); - assert(!pthread_create(&fw_thread, NULL, run_forwarding, NULL)); - - run_reverse_forwarding(NULL); - return 0; -} diff --git a/lab3/link_emulator/link.h b/lab3/link_emulator/link.h deleted file mode 100644 index 92b64db..0000000 --- a/lab3/link_emulator/link.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef LINK -#define LINK -#include "lib.h" - -typedef struct { - msg* m; - unsigned long long finish_time; -} msg_in_flight; - -#endif diff --git a/lab3/link_emulator/queue.c b/lab3/link_emulator/queue.c deleted file mode 100644 index daced7e..0000000 --- a/lab3/link_emulator/queue.c +++ /dev/null @@ -1,61 +0,0 @@ -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include "queue.h" - -void enqueue(queue* q,void* m){ - if (q->first==NULL){ - assert(q->last==NULL); - - q->first = (queue_entry*)malloc(sizeof(queue_entry)); - q->last = q->first; - } - else { - queue_entry * t = (queue_entry*)malloc(sizeof(queue_entry)); - q->first->prev = t; - q->first = t; - } - - q->first->prev = NULL; - q->first->crt = m; - - q->size++; -} - -void* dequeue(queue* q){ - queue_entry * t; - void* m; - - if (q->first==NULL){ - assert(q->size==0); - return NULL; - } - else if (q->first==q->last){ - t = q->last; - assert(q->first->prev==NULL); - - q->first = q->last = NULL; - } - else { - t = q->last; - q->last = q->last->prev; - } - - m = t->crt; - free(t); - q->size--; - - return m; -} - -queue* create_queue(){ - queue* q = (queue*)malloc(sizeof(queue)); - q->first = NULL; - q->last = NULL; - q->size = 0; - return q; -} - -void destroy_queue(queue* q){ - assert(0); -} diff --git a/lab3/link_emulator/queue.h b/lab3/link_emulator/queue.h deleted file mode 100644 index 9b6a45b..0000000 --- a/lab3/link_emulator/queue.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef QUEUE -#define QUEUE -#include "lib.h" - - -struct q { - void* crt; - struct q* prev; -}; - -typedef struct q queue_entry; - -typedef struct { - int size; - queue_entry* first; - queue_entry* last; -} queue; - -void enqueue(queue* q,void* m); -void* dequeue(queue* q); - -queue* create_queue(); -void destroy_queue(queue* q); - -#endif diff --git a/lab3/recv.c b/lab3/recv.c index 0372ee4..84f3e99 100644 --- a/lab3/recv.c +++ b/lab3/recv.c @@ -6,7 +6,14 @@ #include <arpa/inet.h> #include "common.h" #include "link_emulator/lib.h" - +#include "include/utils.h" + +/** + * You can change these to communicate with another colleague. + * There are several factors that could stop this from working over the + * internet, but if you're on the same network it should work. + * Just fill in their IP here and make sure that you use the same port. + */ #define HOST "127.0.0.1" #define PORT 10001 @@ -19,10 +26,7 @@ int main(int argc,char** argv) { /* Receive the frame from the link */ int len = link_recv(&t, sizeof(struct l3_msg)); - if (len < 0){ - perror("Receive message"); - return -1; - } + DIE(len < 0, "Receive message"); /* We have to convert it to host order */ uint32_t recv_sum = ntohl(t.hdr.sum); diff --git a/lab3/run_experiment.sh b/lab3/run_experiment.sh deleted file mode 100755 index 7381313..0000000 --- a/lab3/run_experiment.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -SPEED=1 -DELAY=1 -LOSS=0 -# Adjust the corruption -CORRUPT=80 - -# Second bit corruption rate -CORRUPT2=0 - -{ - pkill -9 link - pkill -9 recv - pkill -9 send -} &> /dev/null - -./link_emulator/link speed=$SPEED delay=$DELAY loss=$LOSS corrupt=$CORRUPT corrupt2=$CORRUPT2 & -sleep 1 -./recv & -sleep 1 - -./send diff --git a/lab3/run_experiment.sh b/lab3/run_experiment.sh new file mode 120000 index 0000000..a204cff --- /dev/null +++ b/lab3/run_experiment.sh @@ -0,0 +1 @@ +../common/run_experiment.sh \ No newline at end of file diff --git a/lab3/send.c b/lab3/send.c index 0c6e8d4..c9f4e5b 100644 --- a/lab3/send.c +++ b/lab3/send.c @@ -8,6 +8,7 @@ #include "common.h" #include "link_emulator/lib.h" #include <arpa/inet.h> +#include "include/utils.h" #define HOST "127.0.0.1" #define PORT 10000 -- GitLab