소스 검색

Merge pull request #2 from AlexMeuer/master

Add support for delay variance and loss/reorder correlations
Christian Sieber 7 년 전
부모
커밋
f1dae28017
3개의 변경된 파일77개의 추가작업 그리고 35개의 파일을 삭제
  1. 15 5
      README.md
  2. 41 22
      main.py
  3. 21 8
      templates/main.html

+ 15 - 5
README.md

@@ -1,20 +1,30 @@
 # tcgui
 # tcgui
 
 
-A lightweight Python-based Web-GUI for Linux traffic control (tc) to set, view and delete traffic shaping rules. The Web-GUI is intended for short-term isolated testbeds or classroom scenarios and does not contain any security mechanisms.
+A lightweight Python-based Web-GUI for Linux traffic control (`tc`) to set, view and delete traffic shaping rules. The Web-GUI is intended for short-term isolated testbeds or classroom scenarios and does not contain any security mechanisms.
 
 
 No further changes are planned right now, but pull requests are welcome.
 No further changes are planned right now, but pull requests are welcome.
 
 
 ## Requirements
 ## Requirements
 
 
-- tested with ubuntu 16.04 LTS
-- netem tools & python3-flask is required
-    - install with `sudo apt-get install iproute python3-flask`
-- more information: https://calomel.org/network_loss_emulation.html
+- Tested with Ubuntu 16.04 LTS & Raspbian 4.14.98-v7+ (stretch, Debian 9.8)
+- `netem` tools & p`ython3-flask` are required
+    - Install with `sudo apt-get install iproute python3-flask`
+- More information:
+    - https://calomel.org/network_loss_emulation.html
+    - https://wiki.linuxfoundation.org/networking/netem
 
 
 ## Usage
 ## Usage
 
 
 - Execute the main.py file and go to http://localhost:5000:
 - Execute the main.py file and go to http://localhost:5000:
     
     
+    ```
     sudo python3 main.py
     sudo python3 main.py
+    
+    --ip IP               The IP where the server is listening
+    --port PORT           The port where the server is listening
+    --dev [DEV [DEV ...]] The interfaces to restrict to
+    --regex REGEX         A regex to match interfaces
+    --debug               Run Flask in debug mode
+    ```
 
 
 - The tool will read your interfaces and the current setup every time the site is reloaded
 - The tool will read your interfaces and the current setup every time the site is reloaded

+ 41 - 22
main.py

@@ -30,9 +30,12 @@ def main():
 @app.route('/new_rule/<interface>', methods=['POST'])
 @app.route('/new_rule/<interface>', methods=['POST'])
 def new_rule(interface):
 def new_rule(interface):
     delay = request.form['Delay']
     delay = request.form['Delay']
+    delay_variance = request.form['DelayVariance']
     loss = request.form['Loss']
     loss = request.form['Loss']
+    loss_correlation = request.form['LossCorrelation']
     duplicate = request.form['Duplicate']
     duplicate = request.form['Duplicate']
     reorder = request.form['Reorder']
     reorder = request.form['Reorder']
+    reorder_correlation = request.form['ReorderCorrelation']
     corrupt = request.form['Corrupt']
     corrupt = request.form['Corrupt']
     rate = request.form['Rate']
     rate = request.form['Rate']
 
 
@@ -48,12 +51,18 @@ def new_rule(interface):
         command += ' rate %smbit' % rate
         command += ' rate %smbit' % rate
     if delay != '':
     if delay != '':
         command += ' delay %sms' % delay
         command += ' delay %sms' % delay
+        if delay_variance != '':
+            command += ' %sms' % delay_variance
     if loss != '':
     if loss != '':
         command += ' loss %s%%' % loss
         command += ' loss %s%%' % loss
+        if loss_correlation != '':
+            command += ' %s%%' % loss_correlation
     if duplicate != '':
     if duplicate != '':
         command += ' duplicate %s%%' % duplicate
         command += ' duplicate %s%%' % duplicate
     if reorder != '':
     if reorder != '':
         command += ' reorder %s%%' % reorder
         command += ' reorder %s%%' % reorder
+        if reorder_correlation != '':
+            command += ' %s%%' % reorder_correlation
     if corrupt != '':
     if corrupt != '':
         command += ' corrupt %s%%' % corrupt
         command += ' corrupt %s%%' % corrupt
     print(command)
     print(command)
@@ -72,6 +81,7 @@ def remove_rule(interface):
     proc.wait()
     proc.wait()
     return redirect(url_for('main'))
     return redirect(url_for('main'))
 
 
+
 def get_active_rules():
 def get_active_rules():
     proc = subprocess.Popen(['tc', 'qdisc'], stdout=subprocess.PIPE)
     proc = subprocess.Popen(['tc', 'qdisc'], stdout=subprocess.PIPE)
     output = proc.communicate()[0].decode()
     output = proc.communicate()[0].decode()
@@ -79,7 +89,7 @@ def get_active_rules():
     rules = []
     rules = []
     dev = set()
     dev = set()
     for line in lines:
     for line in lines:
-        arguments = line.split(' ')
+        arguments = line.split()
         rule = parse_rule(arguments)
         rule = parse_rule(arguments)
         if rule['name'] and rule['name'] not in dev:
         if rule['name'] and rule['name'] not in dev:
             rules.append(rule)
             rules.append(rule)
@@ -87,40 +97,49 @@ def get_active_rules():
     return rules
     return rules
 
 
 
 
-def parse_rule(splitted_rule):
-    rule = {'name':      None,
-            'rate':      None,
-            'delay':     None,
-            'loss':      None,
-            'duplicate': None,
-            'reorder':   None,
-            'corrupt':   None}
+def parse_rule(split_rule):
+    rule = {'name':               None,
+            'rate':               None,
+            'delay':              None,
+            'delayVariance':      None,
+            'loss':               None,
+            'lossCorrelation':    None,
+            'duplicate':          None,
+            'reorder':            None,
+            'reorderCorrelation': None,
+            'corrupt':            None}
     i = 0
     i = 0
-    for argument in splitted_rule:
+    for argument in split_rule:
         if argument == 'dev':
         if argument == 'dev':
             # Both regex pattern and dev name can be given
             # Both regex pattern and dev name can be given
             # An interface could match the pattern and/or 
             # An interface could match the pattern and/or 
             # be in the interface list
             # be in the interface list
             if pattern is None and dev_list is None:
             if pattern is None and dev_list is None:
-                rule['name'] = splitted_rule[i+1]
+                rule['name'] = split_rule[i + 1]
             if pattern:
             if pattern:
-                if pattern.match(splitted_rule[i+1]) :
-                    rule['name'] = splitted_rule[i+1]
+                if pattern.match(split_rule[i + 1]) :
+                    rule['name'] = split_rule[i + 1]
             if dev_list:
             if dev_list:
-                if splitted_rule[i+1] in dev_list:
-                    rule['name'] = splitted_rule[i+1]
+                if split_rule[i + 1] in dev_list:
+                    rule['name'] = split_rule[i + 1]
         elif argument == 'rate':
         elif argument == 'rate':
-            rule['rate'] = splitted_rule[i + 1].split('Mbit')[0]
+            rule['rate'] = split_rule[i + 1].split('Mbit')[0]
         elif argument == 'delay':
         elif argument == 'delay':
-            rule['delay'] = splitted_rule[i + 1]
+            rule['delay'] = split_rule[i + 1]
+            if 'ms' in split_rule[i + 2]:
+                rule['delayVariance'] = split_rule[i + 2]
         elif argument == 'loss':
         elif argument == 'loss':
-            rule['loss'] = splitted_rule[i + 1]
+            rule['loss'] = split_rule[i + 1]
+            if '%' in split_rule[i + 2]:
+                rule['lossCorrelation'] = split_rule[i + 2]
         elif argument == 'duplicate':
         elif argument == 'duplicate':
-            rule['duplicate'] = splitted_rule[i + 1]
+            rule['duplicate'] = split_rule[i + 1]
         elif argument == 'reorder':
         elif argument == 'reorder':
-            rule['reorder'] = splitted_rule[i + 1]
+            rule['reorder'] = split_rule[i + 1]
+            if '%' in split_rule[i + 2]:
+                rule['reorderCorrelation'] = split_rule[i + 2]
         elif argument == 'corrupt':
         elif argument == 'corrupt':
-            rule['corrupt'] = splitted_rule[i + 1]
+            rule['corrupt'] = split_rule[i + 1]
         i += 1
         i += 1
     return rule
     return rule
 
 
@@ -133,7 +152,7 @@ if __name__ == "__main__":
         pattern = re.compile(args.regex)
         pattern = re.compile(args.regex)
     if args.dev:
     if args.dev:
         dev_list = args.dev
         dev_list = args.dev
-    app_args={}
+    app_args = {}
     if args.ip:
     if args.ip:
         app_args['host'] = args.ip
         app_args['host'] = args.ip
     if args.port:
     if args.port:

+ 21 - 8
templates/main.html

@@ -16,36 +16,44 @@
                         <th>Name</th>
                         <th>Name</th>
                         <th>Current Value</th>
                         <th>Current Value</th>
                         <th>New Value</th>
                         <th>New Value</th>
+                        <th>Variance / Correlation</th>
+                        <th>New Value</th>
                     </tr>
                     </tr>
                     <tr>
                     <tr>
                         <td>Rate:</td>
                         <td>Rate:</td>
-                        <td>{{ rule['rate'] }}</td>
-                        <td><input type="text" name="Rate" size="5"> in Mbit</td>
+			<td>{{ rule['rate'] }}</td>
+                        <td><input type="number" name="Rate" size="5"> Mbit</td>
                     </tr>
                     </tr>
                     <tr>
                     <tr>
                         <td>Delay:</td>
                         <td>Delay:</td>
                         <td>{{ rule['delay'] }}</td>
                         <td>{{ rule['delay'] }}</td>
-                        <td><input type="text" name="Delay" size="5"> in ms</td>
+                        <td><input type="number" name="Delay" size="5"> ms</td>
+                        <td>±{{ rule['delayVariance'] }}</td>
+                        <td>±<input type="number" name="DelayVariance" size="5"> ms</td>
                     </tr>
                     </tr>
                     <tr>
                     <tr>
                         <td>Loss:</td>
                         <td>Loss:</td>
                         <td>{{ rule['loss'] }}</td>
                         <td>{{ rule['loss'] }}</td>
-                        <td><input type="text" name="Loss" size="5"> in %</td>
+                        <td><input type="number" name="Loss" size="5"> %</td>
+                        <td>{{ rule['lossCorrelation'] }}</td>
+                        <td><input type="number" name="LossCorrelation" size="5"> %</td>
                     </tr>
                     </tr>
                     <tr>
                     <tr>
                         <td>Duplicate:</td>
                         <td>Duplicate:</td>
                         <td>{{ rule['duplicate'] }}</td>
                         <td>{{ rule['duplicate'] }}</td>
-                        <td><input type="text" name="Duplicate" size="5"> in %</td>
+                        <td><input type="number" name="Duplicate" size="5"> %</td>
                     </tr>
                     </tr>
                     <tr>
                     <tr>
                         <td>Reorder:</td>
                         <td>Reorder:</td>
                         <td>{{ rule['reorder'] }}</td>
                         <td>{{ rule['reorder'] }}</td>
-                        <td><input type="text" name="Reorder" size="5"> in %</td>
+                        <td><input type="number" name="Reorder" size="5"> %</td>
+                        <td>{{ rule['reorderCorrelation'] }}</td>
+                        <td><input type="number" name="ReorderCorrelation" size="5"> %</td>
                     </tr>
                     </tr>
                     <tr>
                     <tr>
                         <td>Corrupt</td>
                         <td>Corrupt</td>
                         <td>{{ rule['corrupt'] }}</td>
                         <td>{{ rule['corrupt'] }}</td>
-                        <td><input type="text" name="Corrupt" size="5"> in %</td>
+                        <td><input type="number" name="Corrupt" size="5"> %</td>
                     </tr>
                     </tr>
                 </table>
                 </table>
                 <input type="submit" value="Apply Rules">
                 <input type="submit" value="Apply Rules">
@@ -56,5 +64,10 @@
         </li>
         </li>
     {% endfor %}
     {% endfor %}
 </ul>
 </ul>
+<style>
+    th,td {
+        text-align: center;
+    }
+</style>
 </body>
 </body>
-</html>
+</html>