def test_agent_crash_dns_malformed_received(self): '''Verify that Agent do not crash on sending a malformed DNS packet. This Test case specifically test following Bug Bug Id 1566067 : "Agent crash at BindUtil::DnsClass" Steps: 1. Create a VN with IPAM having Virtual DNS configured. 2. Create a VM and send a DNS query from VM to DNS server. DNS server should have the Qclass field as any value other than "01" 3. Verify that no crash happens when this malformed DNS packet reaches the server Pass criteria: Vrouter agent should not crash on receiving a malformed DNS packet Maintainer: [email protected]''' vm_list = ['vm1', 'vm2'] vn_name = 'vn1' vn_nets = {'vn1' : '10.10.10.0/24'} dns_server_name = 'vdns1' domain_name = 'juniper.net' ttl = 100 ipam_name = 'ipam1' dns_data = VirtualDnsType( domain_name=domain_name, dynamic_records_from_client=True, default_ttl_seconds=ttl, record_order='random', reverse_resolution=True) vdns_fixt1 = self.useFixture(VdnsFixture(self.inputs, self.connections, vdns_name=dns_server_name, dns_data=dns_data)) result, msg = vdns_fixt1.verify_on_setup() self.assertTrue(result, msg) dns_server = IpamDnsAddressType( virtual_dns_server_name=vdns_fixt1.vdns_fq_name) ipam_mgmt_obj = IpamType( ipam_dns_method='virtual-dns-server', ipam_dns_server=dns_server) # Associate IPAM with VDNS server Object ipam_fixt1 = self.useFixture(IPAMFixture(ipam_name, vdns_obj=vdns_fixt1.obj, connections=self.connections, ipamtype=ipam_mgmt_obj)) # Launch VM with VN Created above. vn_fixt = self.useFixture(VNFixture(self.connections, self.inputs, vn_name=vn_name, subnets=[vn_nets['vn1']], ipam_fq_name=ipam_fixt1.fq_name, option='contrail')) vm_fixture1 = self.useFixture(VMFixture(project_name=self.inputs.project_name, connections=self.connections, vn_obj=vn_fixt.obj, vm_name=vm_list[0], image_name = "ubuntu-traffic")) assert vm_fixture1.verify_vm_launched() assert vm_fixture1.verify_on_setup() assert vm_fixture1.wait_till_vm_is_up() # DNS payload with 1 query and qclass as "04" instead of "01" filters = '\'(src host %s and dst host %s and port 1234)\'' \ % (vm_fixture1.vm_ip,vn_fixt.get_dns_ip(ipam_fq_name = ipam_fixt1.fq_name)) session, pcap = start_tcpdump_for_vm_intf(self, vm_fixture1, vn_fixt.vn_fq_name, filters = filters) dnsPayload = '\x12\x34\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x04' streamObj = Stream(protocol="ip", sport=1234, dport=53, proto='udp', src=vm_fixture1.vm_ip, dst=vn_fixt.get_dns_ip(ipam_fq_name =ipam_fixt1.fq_name)) profile_kwargs = {'stream': streamObj, 'count' : 10, 'payload': dnsPayload} profileObj = StandardProfile(**profile_kwargs) tx_vm_node_ip = vm_fixture1.vm_node_ip send_node = Host( tx_vm_node_ip, self.inputs.host_data[tx_vm_node_ip]['username'], self.inputs.host_data[tx_vm_node_ip]['password']) send_host = Host(vm_fixture1.local_ip, vm_fixture1.vm_username, vm_fixture1.vm_password) sender = Sender("senddns", profileObj, send_node, send_host, self.inputs.logger) sender.start() sleep(1) sender.poll() if not sender.sent: self.logger.error("Failed to Transmit packet") assert False, "Failed to Transmit packet" sender.stop() sleep(2) stop_tcpdump_for_vm_intf(self, session, pcap) sleep(2) # grep in pcap file with source port (1234) assert verify_tcpdump_count(self, session, pcap, grep_string="1234", exp_count=10)
def startTraffic( self, name='stream', num_streams=1, start_port=9100, tx_vm_fixture=None, rx_vm_fixture=None, stream_proto='udp', vm_fip_info=None, packet_size=100, cfg_profile='ContinuousProfile', start_sport=8000, total_single_instance_streams=20, chksum=False, pps=100, fip=None, tx_vn_fixture=None, rx_vn_fixture=None, af=None): ''' Start traffic based on inputs given.. Return {'status': True, 'msg': None} if traffic started successfully..else return {'status': False, 'msg': err_msg}.. Details on inputs: name : Stream identifier; num_streams : number of separate sendpkts instance streams [will take more memory] start_port : Destination start port if num_streams is used tx_vm_fixture & rx_vm_fixture : Needed for vm_ip and vm_mdata_ip [to access vm from compute] stream_proto : TCP, UDP or ICMP; packet_size : if custom size if needed start_sport : if ContinuousSportRange is used, only supports UDP, starting number for source port total_single_instance_streams : if ContinuousSportRange is used, specify number of streams pps :Number of packets to launch per sec ContinuousSportRange launches n streams @defined pps, with one instance of sendpkts.. ''' self.logger.info("startTraffic data: name- %s, stream_proto-%s, packet_size-%s, total_single_instance_streams-%s, chksum-%s, pps-%s" % (name, stream_proto, packet_size, total_single_instance_streams, chksum, pps)) status = True msg = None self.packet_size = packet_size self.chksum = chksum self.start_port = start_port self.start_sport = start_sport self.endport = start_sport + total_single_instance_streams self.total_single_instance_streams = total_single_instance_streams self.tx_vm_fixture = tx_vm_fixture self.rx_vm_fixture = rx_vm_fixture tx_vn_fq_name = tx_vn_fixture.get_vn_fq_name() if tx_vn_fixture else None rx_vn_fq_name = rx_vn_fixture.get_vn_fq_name() if rx_vn_fixture else None af = af if af is not None else self.inputs.get_af() self.stream_proto = stream_proto self.vm_fip_info = vm_fip_info self.traffic_fip = False if self.vm_fip_info == None: self.traffic_fip = False else: self.traffic_fip = True if not self.traffic_fip: self.tx_vm_node_ip = self.tx_vm_fixture.vm_node_ip self.rx_vm_node_ip = self.rx_vm_fixture.vm_node_ip self.tx_local_host = Host( self.tx_vm_node_ip, self.inputs.host_data[self.tx_vm_node_ip]['username'], self.inputs.host_data[self.tx_vm_node_ip]['password']) self.rx_local_host = Host( self.rx_vm_node_ip, self.inputs.host_data[self.rx_vm_node_ip]['username'], self.inputs.host_data[self.rx_vm_node_ip]['password']) self.send_host = Host(self.tx_vm_fixture.local_ip, self.tx_vm_fixture.vm_username, self.tx_vm_fixture.vm_password) self.recv_host = Host(self.rx_vm_fixture.local_ip, self.rx_vm_fixture.vm_username, self.rx_vm_fixture.vm_password) else: self.tx_vm_node_ip = None self.rx_vm_node_ip = None self.tx_local_host = Host( self.inputs.cfgm_ip, self.inputs.host_data[self.tx_vm_node_ip]['username'], self.inputs.host_data[self.tx_vm_node_ip]['password']) self.rx_local_host = Host( self.inputs.cfgm_ip, self.inputs.host_data[self.rx_vm_node_ip]['username'], self.inputs.host_data[self.rx_vm_node_ip]['password']) self.send_host = Host(self.vm_fip_info[self.tx_vm_fixture.vm_name]) self.recv_host = Host(self.vm_fip_info[self.rx_vm_fixture.vm_name]) self.sender = list() self.receiver = list() self.num_streams = 0 if fip is None: self.dst_ips = list(); self.src_ips = list() if af == 'dual' or af == 'v4': self.src_ips.extend(self.tx_vm_fixture.get_vm_ips( vn_fq_name=tx_vn_fq_name, af='v4')) self.dst_ips.extend(self.rx_vm_fixture.get_vm_ips( vn_fq_name=rx_vn_fq_name, af='v4')) if af == 'dual' or af == 'v6': self.src_ips.extend(self.tx_vm_fixture.get_vm_ips( vn_fq_name=tx_vn_fq_name, af='v6')) self.dst_ips.extend(self.rx_vm_fixture.get_vm_ips( vn_fq_name=rx_vn_fq_name, af='v6')) else: self.dst_ips = [fip] self.src_ips = [self.tx_vm_fixture.vm_ip] if len(self.dst_ips) > len(self.src_ips): raise Exception('No of destination ips cant be greater than' ' source ips, for multi stream case') for index in range(len(self.dst_ips)): name = name + '_dst' + str(index) + '_' for i in range(num_streams): self.name = name + self.stream_proto + str(i) self.dport = start_port + i m = "Send protocol %s traffic to port %s" % ( self.stream_proto, self.dport) if self.stream_proto == 'icmp': m = "Send protocol %s traffic" % self.stream_proto self.logger.info(m) stream = Stream(proto=self.stream_proto, src=self.src_ips[index], dst=self.dst_ips[index], dport=self.dport) if fip: listener = self.rx_vm_fixture.vm_ip else: listener = self.dst_ips[index] # stream profile... if cfg_profile == 'ContinuousSportRange': profile = ContinuousSportRange(stream=stream, startport=self.start_sport, endport=self.endport, listener=listener, size=self.packet_size, chksum=self.chksum, pps=pps) elif cfg_profile == 'ContinuousProfile': profile = ContinuousProfile(stream=stream, listener=listener, size=self.packet_size, chksum=self.chksum) # sender profile... sender = Sender(self.name, profile, self.tx_local_host, self.send_host, self.inputs.logger) receiver = Receiver(self.name, profile, self.rx_local_host, self.recv_host, self.inputs.logger) self.logger.info("tx vm - node %s, mdata_ip %s, vm_ip %s" %( self.tx_local_host.ip, self.send_host.ip, self.src_ips[index])) self.logger.info("rx vm - node %s, mdata_ip %s, vm_ip %s" %( self.rx_local_host.ip, self.recv_host.ip, self.dst_ips[index])) receiver.start() self.logger.info("Starting %s traffic from %s to %s" %( self.stream_proto, self.src_ips[index], self.dst_ips[index])) sender.start() retries = 10 j = 0 sender.sent = None while j < retries and sender.sent == None: # wait before checking for stats as it takes time for file # update with stats time.sleep(5) sender.poll() # end while if sender.sent == None: msg = "send %s traffic failure from %s " % ( self.stream_proto, self.src_ips[index]) self.logger.info( "traffic tx stats not available !!, details: %s" % msg) else: self.logger.info( "traffic running good, sent %s pkts so far.." % sender.sent) self.sender.append(sender) self.receiver.append(receiver) self.num_streams += 1 if msg != None: status = False return {'status': status, 'msg': msg}