..
..
.. Licensed under the Apache License, Version 2.0 (the "License");
.. you may not use this file except in compliance with the License.
.. You may obtain a copy of the License at
..
..     http://www.apache.org/licenses/LICENSE-2.0
..
.. Unless required by applicable law or agreed to in writing, software
.. distributed under the License is distributed on an "AS IS" BASIS,
.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
.. See the License for the specific language governing permissions and
.. limitations under the License.
..

.. _faq:

***
FAQ
***

Who is using Traffic Control?
=============================
- `Comcast Cable <http://www.comcast.com/>`_ is the original developer of Traffic Control and is using it for all it's IP video delivery, delivering images and software to it's X1 platform, and for `delivering third party content <https://www.comcastwholesale.com/products-services/content-delivery-network>`_ to it's footprint.
- `Cox Communications <http://www.cox.com/>`_
- `Cisco <http://www.cisco.com/>`_ has a product called `Open Media Distribution <http://www.cisco.com/c/en/us/products/video/open-media-distribution/index.html>`_ that is based on Traffic Control.
- `Concurrent <https://www.ccur.com/>`_ has a product that uses Traffic Control, see their `github page <https://github.com/concurrentlabs/laguna>`_ for more info.
- `Augere Pakistan / QUBEE <http://www.qubee.com.pk>`_
- `Qwilt <https://www.qwilt.com/>`_ has a product called `Open Edge CDN <https://qwilt.com/solutions/edge-cloud-cdn/>`_ that is based on Traffic Control.

How do I get help with Traffic Control?
=======================================
Join us at ``#traffic-control`` on the `ASF Slack <https://s.apache.org/tc-slack-request>`_ or send your questions to our `mailing list <mailto:users@trafficcontrol.apache.org>`_.  Slack is usually the best forum for quick Q&A type issues -- like when you are getting a Traffic Control CDN up and running or if you have a question about configuration. Any discussions that could potentially lead to decisions being made about the project -- like a new feature -- should happen on `the developer mailing list <mailto:dev@trafficcontrol.apache.org>`_-.

How do I get involved with the development of Traffic Control?
==============================================================
See the :atc-file:`CONTRIBUTING.md` file.

What is Rascal?
===============
Rascal was the original name for Traffic Monitor. You will sometimes still see this name in the source, or in older documents.

What is the CCR?
================
:abbr:`CCR (Comcast Content Router)` was the original name for Traffic Router. You will sometimes still see this name in the source, or in older documents.

What is Twelve Monkeys?
=======================
Twelve Monkeys was the the original internal name for Traffic Ops. You will sometimes still see this name in the source, or in older documents. It's also a good movie.

What license is Traffic Control released under?
===============================================
See the :atc-file:`LICENSE` file.
