• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2021-2022 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15# -----------------------------------------------------------------------------
16# Imports
17# -----------------------------------------------------------------------------
18import asyncio
19import logging
20
21from .common import Transport, ParserSource
22
23# -----------------------------------------------------------------------------
24# Logging
25# -----------------------------------------------------------------------------
26logger = logging.getLogger(__name__)
27
28
29# -----------------------------------------------------------------------------
30async def open_udp_transport(spec: str) -> Transport:
31    '''
32    Open a UDP transport.
33    The parameter string has this syntax:
34    <local-host>:<local-port>,<remote-host>:<remote-port>
35
36    Example: 0.0.0.0:9000,127.0.0.1:9001
37    '''
38
39    class UdpPacketSource(asyncio.DatagramProtocol, ParserSource):
40        def datagram_received(self, data, addr):
41            self.parser.feed_data(data)
42
43    class UdpPacketSink:
44        def __init__(self, transport):
45            self.transport = transport
46
47        def on_packet(self, packet):
48            self.transport.sendto(packet)
49
50        def close(self):
51            self.transport.close()
52
53    local, remote = spec.split(',')
54    local_host, local_port = local.split(':')
55    remote_host, remote_port = remote.split(':')
56    (
57        udp_transport,
58        packet_source,
59    ) = await asyncio.get_running_loop().create_datagram_endpoint(
60        UdpPacketSource,
61        local_addr=(local_host, int(local_port)),
62        remote_addr=(remote_host, int(remote_port)),
63    )
64    packet_sink = UdpPacketSink(udp_transport)
65
66    return Transport(packet_source, packet_sink)
67